mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
Merge pull request #3957 from penpot/eva-remove-new-css-phase-3
♻️ Remove new-css-system phase 3
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -305,6 +305,11 @@
|
||||
--resize-area-background-color: var(--color-background-primary);
|
||||
--resize-area-border-color: var(--color-background-quaternary);
|
||||
|
||||
--flow-tag-background-color: var(--color-background-tertiary);
|
||||
--flow-tag-foreground-color: var(--color-foreground-secondary);
|
||||
--flow-tag-background-color-hover: var(--color-accent-primary);
|
||||
--flow-tag-foreground-color-hover: var(--color-background-primary);
|
||||
|
||||
// VIEWER
|
||||
--viewer-background-color: var(--color-background-secondary);
|
||||
--viewer-paginator-background-color: var(--color-background-tertiary);
|
||||
|
||||
@@ -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,26 +57,16 @@
|
||||
@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";
|
||||
@import "main/partials/project-bar";
|
||||
@import "main/partials/sidebar";
|
||||
@import "main/partials/sidebar-document-history";
|
||||
@import "main/partials/tab-container";
|
||||
@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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
(:require
|
||||
[app.main.data.modal :as modal]
|
||||
[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 :as i18n :refer [tr]]
|
||||
@@ -27,8 +26,8 @@
|
||||
hint
|
||||
accept-label
|
||||
accept-style] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
on-accept (or on-accept identity)
|
||||
|
||||
(let [on-accept (or on-accept identity)
|
||||
message (or message (tr "ds.alert-title"))
|
||||
accept-label (or accept-label (tr "ds.alert-ok"))
|
||||
accept-style (or accept-style :danger)
|
||||
@@ -50,54 +49,26 @@
|
||||
(on-accept props)))]
|
||||
(->> (events/listen js/document "keydown" on-keydown)
|
||||
(partial events/unlistenByKey))))
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click accept-fn} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click accept-fn} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 {:class (stl/css :modal-msg)} message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-message])
|
||||
(when (string? hint)
|
||||
[:p {:class (stl/css :modal-hint)} hint])]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 {:class (stl/css :modal-msg)} message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-message])
|
||||
(when (string? hint)
|
||||
[:p {:class (stl/css :modal-hint)} hint])]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.alert-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 title]]
|
||||
[:div.modal-close-button
|
||||
{:on-click accept-fn} i/close]]
|
||||
|
||||
[:div.modal-content
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 scd-message])
|
||||
(when (string? hint)
|
||||
[:p hint])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:input.accept-button
|
||||
{:class (dom/classnames
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]))
|
||||
|
||||
@@ -11,39 +11,45 @@
|
||||
&.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.modal-hint {
|
||||
@include titleTipography;
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
}
|
||||
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.modal-hint {
|
||||
@include titleTipography;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
[app.main.ui.auth.recovery :refer [recovery-page]]
|
||||
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
|
||||
[app.main.ui.auth.register :refer [register-page register-success-page register-validate-page]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
@@ -20,102 +19,57 @@
|
||||
|
||||
(mf/defc terms-login
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
|
||||
(let [show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
|
||||
show-terms? (some? cf/terms-of-service-uri)
|
||||
show-privacy? (some? cf/privacy-policy-uri)]
|
||||
|
||||
(if new-css-system
|
||||
(when show-all?
|
||||
[:div {:class (stl/css :terms-login)}
|
||||
(when show-terms?
|
||||
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
|
||||
(when show-all?
|
||||
[:div {:class (stl/css :terms-login)}
|
||||
(when show-terms?
|
||||
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
|
||||
|
||||
(when show-all?
|
||||
[:span (tr "labels.and")])
|
||||
(when show-all?
|
||||
[:span (tr "labels.and")])
|
||||
|
||||
(when show-privacy?
|
||||
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])
|
||||
|
||||
(when show-all?
|
||||
[:div.terms-login
|
||||
(when show-terms?
|
||||
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
|
||||
|
||||
(when show-all?
|
||||
[:span (tr "labels.and")])
|
||||
|
||||
(when show-privacy?
|
||||
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])]))))
|
||||
(when show-privacy?
|
||||
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])))
|
||||
|
||||
(mf/defc auth
|
||||
[{: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])
|
||||
params (:query-params route)
|
||||
show-illustration? (contains? cf/flags :login-illustration)]
|
||||
|
||||
(mf/use-effect
|
||||
#(dom/set-html-title (tr "title.default")))
|
||||
|
||||
(if new-css-system
|
||||
[:main {:class (stl/css-case :auth-section true
|
||||
:no-illustration (not show-illustration?))}
|
||||
(when show-illustration?
|
||||
[:div {:class (stl/css :login-illustration)}
|
||||
i/login-illustration])
|
||||
[:main {:class (stl/css-case :auth-section true
|
||||
:no-illustration (not show-illustration?))}
|
||||
(when show-illustration?
|
||||
[:div {:class (stl/css :login-illustration)}
|
||||
i/login-illustration])
|
||||
|
||||
[:section {:class (stl/css :auth-content)}
|
||||
[:*
|
||||
[:a {:href "#/" :class (stl/css :logo-btn)}i/logo]
|
||||
(case section
|
||||
:auth-register
|
||||
[:& register-page {:params params}]
|
||||
[:section {:class (stl/css :auth-content)}
|
||||
[:*
|
||||
[:a {:href "#/" :class (stl/css :logo-btn)} i/logo]
|
||||
(case section
|
||||
:auth-register
|
||||
[:& register-page {:params params}]
|
||||
|
||||
:auth-register-validate
|
||||
[:& register-validate-page {:params params}]
|
||||
:auth-register-validate
|
||||
[:& register-validate-page {:params params}]
|
||||
|
||||
:auth-register-success
|
||||
[:& register-success-page {:params params}]
|
||||
:auth-register-success
|
||||
[:& register-success-page {:params params}]
|
||||
|
||||
:auth-login
|
||||
[:& login-page {:params params}]
|
||||
:auth-login
|
||||
[:& login-page {:params params}]
|
||||
|
||||
:auth-recovery-request
|
||||
[:& recovery-request-page]
|
||||
:auth-recovery-request
|
||||
[:& recovery-request-page]
|
||||
|
||||
:auth-recovery
|
||||
[:& recovery-page {:params params}])]
|
||||
:auth-recovery
|
||||
[:& recovery-page {:params params}])]
|
||||
|
||||
(when (contains? #{:auth-login :auth-register} section)
|
||||
[:& terms-login])]]
|
||||
|
||||
;; OLD
|
||||
[:main.auth
|
||||
[:section.auth-sidebar
|
||||
[:a.logo {:href "#/"}
|
||||
[:span {:aria-hidden true} i/logo]
|
||||
[:span.hidden-name "Home"]]
|
||||
[:span.tagline (tr "auth.sidebar-tagline")]]
|
||||
|
||||
[:section.auth-content
|
||||
(case section
|
||||
:auth-register
|
||||
[:& register-page {:params params}]
|
||||
|
||||
:auth-register-validate
|
||||
[:& register-validate-page {:params params}]
|
||||
|
||||
:auth-register-success
|
||||
[:& register-success-page {:params params}]
|
||||
|
||||
:auth-login
|
||||
[:& login-page {:params params}]
|
||||
|
||||
:auth-recovery-request
|
||||
[:& recovery-request-page]
|
||||
|
||||
:auth-recovery
|
||||
[:& recovery-page {:params params}])
|
||||
|
||||
[:& terms-login {}]]])))
|
||||
(when (contains? #{:auth-login :auth-register} section)
|
||||
[:& terms-login])]]))
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
[app.main.ui.components.button-link :as bl]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.components.link :as lk]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.messages :as msgs]
|
||||
[app.util.dom :as dom]
|
||||
@@ -94,8 +93,7 @@
|
||||
|
||||
(mf/defc login-form
|
||||
[{:keys [params on-success-callback origin] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
error (mf/use-state false)
|
||||
form (fm/use-form :spec ::login-form
|
||||
:validators [handle-error-messages]
|
||||
@@ -157,156 +155,86 @@
|
||||
(mf/use-fn
|
||||
#(st/emit! (rt/nav :auth-recovery-request)))]
|
||||
|
||||
(if new-css-system
|
||||
[:*
|
||||
(when-let [message @error]
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content message
|
||||
:on-close #(reset! error nil)
|
||||
:data-test "login-banner"
|
||||
:role "alert"}])
|
||||
[:*
|
||||
(when-let [message @error]
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content message
|
||||
:on-close #(reset! error nil)
|
||||
:data-test "login-banner"
|
||||
:role "alert"}])
|
||||
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:name :email
|
||||
:type "email"
|
||||
:label (tr "auth.email")
|
||||
:class (stl/css :form-field)}]]
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:name :email
|
||||
:type "email"
|
||||
:label (tr "auth.email")
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password
|
||||
:label (tr "auth.password")
|
||||
:class (stl/css :form-field)}]]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password
|
||||
:label (tr "auth.password")
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
(when (and (not= origin :viewer)
|
||||
(or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)))
|
||||
[:div {:class (stl/css :fields-row :forgot-password)}
|
||||
[:& lk/link {:action on-recovery-request
|
||||
:data-test "forgot-password"}
|
||||
(tr "auth.forgot-password")]])
|
||||
(when (and (not= origin :viewer)
|
||||
(or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)))
|
||||
[:div {:class (stl/css :fields-row :forgot-password)}
|
||||
[:& lk/link {:action on-recovery-request
|
||||
:data-test "forgot-password"}
|
||||
(tr "auth.forgot-password")]])
|
||||
|
||||
[:div {:class (stl/css :buttons-stack)}
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-submit")
|
||||
:data-test "login-submit"
|
||||
:class (stl/css :login-button)}])
|
||||
[:div {:class (stl/css :buttons-stack)}
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-submit")
|
||||
:data-test "login-submit"
|
||||
:class (stl/css :login-button)}])
|
||||
|
||||
(when (contains? cf/flags :login-with-ldap)
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-with-ldap-submit")
|
||||
:on-click on-submit-ldap}])]]]
|
||||
|
||||
|
||||
;; OLD
|
||||
[:*
|
||||
(when-let [message @error]
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content message
|
||||
:on-close #(reset! error nil)
|
||||
:data-test "login-banner"
|
||||
:role "alert"}])
|
||||
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div.fields-row
|
||||
[:& fm/input
|
||||
{:name :email
|
||||
:type "email"
|
||||
:help-icon i/at
|
||||
:label (tr "auth.email")
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:div.fields-row
|
||||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password
|
||||
:help-icon i/eye
|
||||
:label (tr "auth.password")
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:div.buttons-stack
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-submit")
|
||||
:data-test "login-submit"}])
|
||||
|
||||
(when (contains? cf/flags :login-with-ldap)
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-with-ldap-submit")
|
||||
:on-click on-submit-ldap}])]]])))
|
||||
(when (contains? cf/flags :login-with-ldap)
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-with-ldap-submit")
|
||||
:on-click on-submit-ldap}])]]]))
|
||||
|
||||
(mf/defc login-buttons
|
||||
[{:keys [params] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
|
||||
(let [login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
|
||||
login-with-github (mf/use-fn (mf/deps params) #(login-with-oidc % :github params))
|
||||
login-with-gitlab (mf/use-fn (mf/deps params) #(login-with-oidc % :gitlab params))
|
||||
login-with-oidc (mf/use-fn (mf/deps params) #(login-with-oidc % :oidc params))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :auth-buttons)}
|
||||
(when (contains? cf/flags :login-with-google)
|
||||
[:& bl/button-link {:on-click login-with-google
|
||||
:icon i/brand-google
|
||||
:label (tr "auth.login-with-google-submit")
|
||||
:class (stl/css :login-btn :btn-google-auth)}])
|
||||
[:div {:class (stl/css :auth-buttons)}
|
||||
(when (contains? cf/flags :login-with-google)
|
||||
[:& bl/button-link {:on-click login-with-google
|
||||
:icon i/brand-google
|
||||
:label (tr "auth.login-with-google-submit")
|
||||
:class (stl/css :login-btn :btn-google-auth)}])
|
||||
|
||||
(when (contains? cf/flags :login-with-github)
|
||||
[:& bl/button-link {:on-click login-with-github
|
||||
:icon i/brand-github
|
||||
:label (tr "auth.login-with-github-submit")
|
||||
:class (stl/css :login-btn :btn-github-auth)}])
|
||||
(when (contains? cf/flags :login-with-github)
|
||||
[:& bl/button-link {:on-click login-with-github
|
||||
:icon i/brand-github
|
||||
:label (tr "auth.login-with-github-submit")
|
||||
:class (stl/css :login-btn :btn-github-auth)}])
|
||||
|
||||
(when (contains? cf/flags :login-with-gitlab)
|
||||
[:& bl/button-link {:on-click login-with-gitlab
|
||||
:icon i/brand-gitlab
|
||||
:label (tr "auth.login-with-gitlab-submit")
|
||||
:class (stl/css :login-btn :btn-gitlab-auth)}])
|
||||
(when (contains? cf/flags :login-with-gitlab)
|
||||
[:& bl/button-link {:on-click login-with-gitlab
|
||||
:icon i/brand-gitlab
|
||||
:label (tr "auth.login-with-gitlab-submit")
|
||||
:class (stl/css :login-btn :btn-gitlab-auth)}])
|
||||
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:& bl/button-link {:on-click login-with-oidc
|
||||
:icon i/brand-openid
|
||||
:label (tr "auth.login-with-oidc-submit")
|
||||
:class (stl/css :login-btn :btn-oidc-auth)}])]
|
||||
|
||||
[:div.auth-buttons
|
||||
(when (contains? cf/flags :login-with-google)
|
||||
[:& bl/button-link {:on-click login-with-google
|
||||
:icon i/brand-google
|
||||
:label (tr "auth.login-with-google-submit")
|
||||
:class "btn-google-auth"}])
|
||||
|
||||
(when (contains? cf/flags :login-with-github)
|
||||
[:& bl/button-link {:on-click login-with-github
|
||||
:icon i/brand-github
|
||||
:label (tr "auth.login-with-github-submit")
|
||||
:class "btn-github-auth"}])
|
||||
|
||||
(when (contains? cf/flags :login-with-gitlab)
|
||||
[:& bl/button-link {:on-click login-with-gitlab
|
||||
:icon i/brand-gitlab
|
||||
:label (tr "auth.login-with-gitlab-submit")
|
||||
:class "btn-gitlab-auth"}])
|
||||
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:& bl/button-link {:on-click login-with-oidc
|
||||
:icon i/brand-openid
|
||||
:label (tr "auth.login-with-oidc-submit")
|
||||
:class "btn-github-auth"}])])))
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:& bl/button-link {:on-click login-with-oidc
|
||||
:icon i/brand-openid
|
||||
:label (tr "auth.login-with-oidc-submit")
|
||||
:class (stl/css :login-btn :btn-oidc-auth)}])]))
|
||||
|
||||
(mf/defc login-button-oidc
|
||||
[{:keys [params] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
login-oidc
|
||||
(let [login-oidc
|
||||
(mf/use-fn
|
||||
(mf/deps params)
|
||||
(fn [event]
|
||||
@@ -317,69 +245,33 @@
|
||||
(fn [event]
|
||||
(when (k/enter? event)
|
||||
(login-oidc event))))]
|
||||
(if new-css-system
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:div {:class (stl/css :link-entry :link-oidc)}
|
||||
[:a {:tab-index "0"
|
||||
:on-key-down handle-key-down
|
||||
:on-click login-oidc}
|
||||
(tr "auth.login-with-oidc-submit")]])
|
||||
|
||||
;; OLD
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:div.link-entry.link-oidc
|
||||
[:a {:tab-index "0"
|
||||
:on-key-down handle-key-down
|
||||
:on-click login-oidc}
|
||||
(tr "auth.login-with-oidc-submit")]]))))
|
||||
(when (contains? cf/flags :login-with-oidc)
|
||||
[:div {:class (stl/css :link-entry :link-oidc)}
|
||||
[:a {:tab-index "0"
|
||||
:on-key-down handle-key-down
|
||||
:on-click login-oidc}
|
||||
(tr "auth.login-with-oidc-submit")]])))
|
||||
|
||||
(mf/defc login-methods
|
||||
[{:keys [params on-success-callback origin] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
[:*
|
||||
(when show-alt-login-buttons?
|
||||
[:*
|
||||
[:& login-buttons {:params params}]
|
||||
[:*
|
||||
(when show-alt-login-buttons?
|
||||
[:*
|
||||
[:& login-buttons {:params params}]
|
||||
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:hr {:class (stl/css :separator)}])])
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:hr {:class (stl/css :separator)}])])
|
||||
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:& login-form {:params params :on-success-callback on-success-callback :origin origin}])]
|
||||
|
||||
;; OLD
|
||||
[:*
|
||||
(when show-alt-login-buttons?
|
||||
[:*
|
||||
[:span.separator
|
||||
[:span.line]
|
||||
[:span.text (tr "labels.continue-with")]
|
||||
[:span.line]]
|
||||
|
||||
[:& login-buttons {:params params}]
|
||||
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:span.separator
|
||||
[:span.line]
|
||||
[:span.text (tr "labels.or")]
|
||||
[:span.line]])])
|
||||
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:& login-form {:params params :on-success-callback on-success-callback}])])))
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:& login-form {:params params :on-success-callback on-success-callback :origin origin}])])
|
||||
|
||||
(mf/defc login-page
|
||||
[{:keys [params] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
go-register
|
||||
(let [go-register
|
||||
(mf/use-fn
|
||||
#(st/emit! (rt/nav :auth-register {} params)))
|
||||
|
||||
@@ -391,64 +283,33 @@
|
||||
(mf/use-fn
|
||||
#(st/emit! (du/create-demo-profile)))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "login-title"} (tr "auth.login-title")]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "login-title"} (tr "auth.login-title")]
|
||||
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
|
||||
[:& login-methods {:params params}]
|
||||
[:& login-methods {:params params}]
|
||||
|
||||
[:div {:class (stl/css :links)}
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:div {:class (stl/css :link-entry :register)}
|
||||
[:& lk/link {:action on-pass-recovery
|
||||
:data-test "forgot-password"}
|
||||
(tr "auth.forgot-password")]])
|
||||
[:div {:class (stl/css :links)}
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:div {:class (stl/css :link-entry :register)}
|
||||
[:& lk/link {:action on-pass-recovery
|
||||
:data-test "forgot-password"}
|
||||
(tr "auth.forgot-password")]])
|
||||
|
||||
(when (contains? cf/flags :registration)
|
||||
[:div {:class (stl/css :link-entry :register)}
|
||||
[:span (tr "auth.register") " "]
|
||||
[:& lk/link {:action go-register
|
||||
:data-test "register-submit"}
|
||||
(tr "auth.register-submit")]])]
|
||||
(when (contains? cf/flags :registration)
|
||||
[:div {:class (stl/css :link-entry :register)}
|
||||
[:span (tr "auth.register") " "]
|
||||
[:& lk/link {:action go-register
|
||||
:data-test "register-submit"}
|
||||
(tr "auth.register-submit")]])]
|
||||
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div {:class (stl/css :link-entry :demo-account)}
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action on-create-demo-profile
|
||||
:data-test "demo-account-link"}
|
||||
(tr "auth.create-demo-account")]])]
|
||||
|
||||
;; OLD
|
||||
[:div.generic-form.login-form
|
||||
[:div.form-container
|
||||
[:h1 {:data-test "login-title"} (tr "auth.login-title")]
|
||||
|
||||
[:& login-methods {:params params}]
|
||||
|
||||
[:div.links
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:div.link-entry
|
||||
[:& lk/link {:action on-pass-recovery
|
||||
:data-test "forgot-password"}
|
||||
(tr "auth.forgot-password")]])
|
||||
|
||||
(when (contains? cf/flags :registration)
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.register") " "]
|
||||
[:& lk/link {:action go-register
|
||||
:data-test "register-submit"}
|
||||
(tr "auth.register-submit")]])]
|
||||
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div.links.demo
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action on-create-demo-profile
|
||||
:data-test "demo-account-link"}
|
||||
(tr "auth.create-demo-account")]]])]])))
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div {:class (stl/css :link-entry :demo-account)}
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action on-create-demo-profile
|
||||
:data-test "demo-account-link"}
|
||||
(tr "auth.create-demo-account")]])]))
|
||||
|
||||
|
||||
@@ -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")]]]])
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.components.link :as lk]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[beicon.v2.core :as rx]
|
||||
@@ -34,8 +32,7 @@
|
||||
|
||||
(mf/defc recovery-form
|
||||
[{:keys [on-success-callback] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
form (fm/use-form :spec ::recovery-request-form
|
||||
(let [form (fm/use-form :spec ::recovery-request-form
|
||||
:validators [handle-error-messages]
|
||||
:initial {})
|
||||
submitted (mf/use-state false)
|
||||
@@ -77,62 +74,34 @@
|
||||
(reset! form nil)
|
||||
(st/emit! (du/request-profile-recovery params)))))]
|
||||
|
||||
(if new-css-system
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :email
|
||||
:label (tr "auth.email")
|
||||
:type "text"
|
||||
:class (stl/css :form-field)}]]
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :email
|
||||
:label (tr "auth.email")
|
||||
:type "text"
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.recovery-request-submit")
|
||||
:data-test "recovery-resquest-submit"
|
||||
:class (stl/css :recover-btn)}]]
|
||||
|
||||
;; OLD
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:form form}
|
||||
[:div.fields-row
|
||||
[:& fm/input {:name :email
|
||||
:label (tr "auth.email")
|
||||
:help-icon i/at
|
||||
:type "text"}]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.recovery-request-submit")
|
||||
:data-test "recovery-resquest-submit"}]])))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.recovery-request-submit")
|
||||
:data-test "recovery-resquest-submit"
|
||||
:class (stl/css :recover-btn)}]]))
|
||||
|
||||
|
||||
;; --- Recovery Request Page
|
||||
|
||||
(mf/defc recovery-request-page
|
||||
[{:keys [params on-success-callback go-back-callback] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
default-go-back #(st/emit! (rt/nav :auth-login))
|
||||
(let [default-go-back #(st/emit! (rt/nav :auth-login))
|
||||
go-back (or go-back-callback default-go-back)]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)} (tr "auth.recovery-request-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.recovery-request-subtitle")]
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)} (tr "auth.recovery-request-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.recovery-request-subtitle")]
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
|
||||
[:& recovery-form {:params params :on-success-callback on-success-callback}]
|
||||
[:& recovery-form {:params params :on-success-callback on-success-callback}]
|
||||
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:& lk/link {:action go-back
|
||||
:data-test "go-back-link"}
|
||||
(tr "labels.go-back")]]]
|
||||
|
||||
;; old
|
||||
[:section.generic-form
|
||||
[:div.form-container
|
||||
[:h1 (tr "auth.recovery-request-title")]
|
||||
[:div.subtitle (tr "auth.recovery-request-subtitle")]
|
||||
[:& recovery-form {:params params :on-success-callback on-success-callback}]
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:& lk/link {:action go-back
|
||||
:data-test "go-back-link"}
|
||||
(tr "labels.go-back")]]]]])))
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:& lk/link {:action go-back
|
||||
:data-test "go-back-link"}
|
||||
(tr "labels.go-back")]]]))
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
[app.main.ui.auth.login :as login]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.components.link :as lk]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.messages :as msgs]
|
||||
[app.util.i18n :refer [tr tr-html]]
|
||||
@@ -88,8 +87,7 @@
|
||||
|
||||
(mf/defc register-form
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||
form (fm/use-form :spec ::register-form
|
||||
:validators [validate
|
||||
(fm/validate-not-empty :password (tr "auth.password-not-empty"))]
|
||||
@@ -114,133 +112,64 @@
|
||||
(partial handle-prepare-register-error form))))))]
|
||||
|
||||
|
||||
(if new-css-system
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email
|
||||
:label (tr "auth.email")
|
||||
:data-test "email-input"
|
||||
:show-success? true
|
||||
:class (stl/css :form-field)}]]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :password
|
||||
:hint (tr "auth.password-length-hint")
|
||||
:label (tr "auth.password")
|
||||
:show-success? true
|
||||
:type "password"
|
||||
:class (stl/css :form-field)}]]
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email
|
||||
:label (tr "auth.email")
|
||||
:data-test "email-input"
|
||||
:show-success? true
|
||||
:class (stl/css :form-field)}]]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :password
|
||||
:hint (tr "auth.password-length-hint")
|
||||
:label (tr "auth.password")
|
||||
:show-success? true
|
||||
:type "password"
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:data-test "register-form-submit"
|
||||
:class (stl/css :register-btn)}]]
|
||||
|
||||
;; OLD
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:form form}
|
||||
[:div.fields-row
|
||||
[:& fm/input {:type "email"
|
||||
:name :email
|
||||
:help-icon i/at
|
||||
:label (tr "auth.email")
|
||||
:data-test "email-input"}]]
|
||||
[:div.fields-row
|
||||
[:& fm/input {:name :password
|
||||
:hint (tr "auth.password-length-hint")
|
||||
:label (tr "auth.password")
|
||||
:type "password"}]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:data-test "register-form-submit"}]])))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:data-test "register-form-submit"
|
||||
:class (stl/css :register-btn)}]]))
|
||||
|
||||
|
||||
(mf/defc register-methods
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
[:*
|
||||
(when login/show-alt-login-buttons?
|
||||
[:*
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:& login/login-buttons {:params params}]])
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:& register-form {:params params :on-success-callback on-success-callback}]]
|
||||
|
||||
;; OLD
|
||||
[:*
|
||||
(when login/show-alt-login-buttons?
|
||||
[:*
|
||||
[:span.separator
|
||||
[:span.line]
|
||||
[:span.text (tr "labels.continue-with")]
|
||||
[:span.line]]
|
||||
|
||||
[:& login/login-buttons {:params params}]
|
||||
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-ldap))
|
||||
[:span.separator
|
||||
[:span.line]
|
||||
[:span.text (tr "labels.or")]
|
||||
[:span.line]])])
|
||||
|
||||
[:& register-form {:params params :on-success-callback on-success-callback}]])))
|
||||
[:*
|
||||
(when login/show-alt-login-buttons?
|
||||
[:*
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:& login/login-buttons {:params params}]])
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:& register-form {:params params :on-success-callback on-success-callback}]])
|
||||
|
||||
(mf/defc register-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)
|
||||
:data-test "registration-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "registration-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& demo-warning])
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& demo-warning])
|
||||
|
||||
[:& register-methods {:params params}]
|
||||
[:& register-methods {:params params}]
|
||||
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry :account)}
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry :account)}
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
|
||||
:data-test "login-here-link"}
|
||||
(tr "auth.login-here")]]
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
|
||||
:data-test "login-here-link"}
|
||||
(tr "auth.login-here")]]
|
||||
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div {:class (stl/css :link-entry :demo-users)}
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
|
||||
(tr "auth.create-demo-account")]])]]
|
||||
|
||||
;; OLD
|
||||
[:div.form-container
|
||||
[:h1 {:data-test "registration-title"} (tr "auth.register-title")]
|
||||
[:div.subtitle (tr "auth.register-subtitle")]
|
||||
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& demo-warning])
|
||||
|
||||
[:& register-methods {:params params}]
|
||||
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
|
||||
:data-test "login-here-link"}
|
||||
(tr "auth.login-here")]]
|
||||
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
|
||||
(tr "auth.create-demo-account")]])]])))
|
||||
(when (contains? cf/flags :demo-users)
|
||||
[:div {:class (stl/css :link-entry :demo-users)}
|
||||
[:span (tr "auth.create-demo-profile") " "]
|
||||
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
|
||||
(tr "auth.create-demo-account")]])]])
|
||||
|
||||
;; --- PAGE: register validation
|
||||
|
||||
@@ -284,8 +213,7 @@
|
||||
|
||||
(mf/defc register-validate-form
|
||||
[{:keys [params on-success-callback] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
form (fm/use-form :spec ::register-validate-form
|
||||
(let [form (fm/use-form :spec ::register-validate-form
|
||||
:validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))]
|
||||
:initial params)
|
||||
@@ -306,103 +234,55 @@
|
||||
(rx/subs! on-success
|
||||
(partial handle-register-error form))))))]
|
||||
|
||||
(if new-css-system
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :fullname
|
||||
:label (tr "auth.fullname")
|
||||
:type "text"
|
||||
:show-success? true
|
||||
:class (stl/css :form-field)}]]
|
||||
[:& fm/form {:on-submit on-submit :form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :fullname
|
||||
:label (tr "auth.fullname")
|
||||
:type "text"
|
||||
:show-success? true
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
(when (contains? cf/flags :terms-and-privacy-checkbox)
|
||||
(let [terms-label
|
||||
(mf/html
|
||||
[:& tr-html
|
||||
{:tag-name "div"
|
||||
:label "auth.terms-privacy-agreement-md"
|
||||
:params [cf/terms-of-service-uri cf/privacy-policy-uri]}])]
|
||||
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
|
||||
[:& fm/input {:name :accept-terms-and-privacy
|
||||
:class "check-primary"
|
||||
:type "checkbox"
|
||||
:label terms-label}]]))
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:class (stl/css :register-btn)}]]
|
||||
|
||||
;; OLD
|
||||
[:& fm/form {:on-submit on-submit
|
||||
:form form}
|
||||
[:div.fields-row
|
||||
[:& fm/input {:name :fullname
|
||||
:label (tr "auth.fullname")
|
||||
:type "text"}]]
|
||||
|
||||
(when (contains? cf/flags :terms-and-privacy-checkbox)
|
||||
[:div.fields-row.input-visible.accept-terms-and-privacy-wrapper
|
||||
(when (contains? cf/flags :terms-and-privacy-checkbox)
|
||||
(let [terms-label
|
||||
(mf/html
|
||||
[:& tr-html
|
||||
{:tag-name "div"
|
||||
:label "auth.terms-privacy-agreement-md"
|
||||
:params [cf/terms-of-service-uri cf/privacy-policy-uri]}])]
|
||||
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
|
||||
[:& fm/input {:name :accept-terms-and-privacy
|
||||
:class "check-primary"
|
||||
:type "checkbox"}
|
||||
[:span
|
||||
(tr "auth.terms-privacy-agreement")]]
|
||||
[:div.auth-links
|
||||
[:a {:href "https://penpot.app/terms" :target "_blank"} (tr "auth.terms-of-service")]
|
||||
[:span ",\u00A0"]
|
||||
[:a {:href "https://penpot.app/privacy" :target "_blank"} (tr "auth.privacy-policy")]]])
|
||||
:type "checkbox"
|
||||
:label terms-label}]]))
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?}]])))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:class (stl/css :register-btn)}]]))
|
||||
|
||||
|
||||
(mf/defc register-validate-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)
|
||||
:data-test "register-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
[:div {:class (stl/css :auth-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "register-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
|
||||
[:& register-validate-form {:params params}]
|
||||
[:& register-validate-form {:params params}]
|
||||
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry :go-back)}
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
|
||||
(tr "labels.go-back")]]]]
|
||||
|
||||
;; OLD
|
||||
[:div.form-container
|
||||
[:h1 {:data-test "register-title"} (tr "auth.register-title")]
|
||||
[:div.subtitle (tr "auth.register-subtitle")]
|
||||
|
||||
[:& register-validate-form {:params params}]
|
||||
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
|
||||
(tr "labels.go-back")]]]])))
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry :go-back)}
|
||||
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
|
||||
(tr "labels.go-back")]]]])
|
||||
|
||||
(mf/defc register-success-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 :register-success)}
|
||||
[:div {:class (stl/css :notification-icon)} i/icon-verify]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
|
||||
[:div {:class (stl/css :notification-text-email)} (:email params "")]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]]
|
||||
|
||||
;; OLD
|
||||
[:div.form-container
|
||||
[:div.notification-icon i/icon-verify]
|
||||
[:div.notification-text (tr "auth.verification-email-sent")]
|
||||
[:div.notification-text-email (:email params "")]
|
||||
[:div.notification-text (tr "auth.check-your-email")]])))
|
||||
[:div {:class (stl/css :auth-form :register-success)}
|
||||
[:div {:class (stl/css :notification-icon)} i/icon-verify]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
|
||||
[:div {:class (stl/css :notification-text-email)} (:email params "")]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]])
|
||||
|
||||
|
||||
|
||||
@@ -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])))
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[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]]
|
||||
@@ -81,20 +80,18 @@
|
||||
(set! (.-height (.-style node)) "0")
|
||||
(set! (.-height (.-style node)) (str (+ 2 (.-scrollHeight node)) "px")))))
|
||||
|
||||
[:textarea
|
||||
{:ref local-ref
|
||||
:auto-focus autofocus?
|
||||
:on-key-down on-key-down
|
||||
:on-focus on-focus*
|
||||
:on-blur on-blur
|
||||
:value value
|
||||
:placeholder placeholder
|
||||
:on-change on-change*}]))
|
||||
[:textarea {:ref local-ref
|
||||
:auto-focus autofocus?
|
||||
:on-key-down on-key-down
|
||||
:on-focus on-focus*
|
||||
:on-blur on-blur
|
||||
:value value
|
||||
:placeholder placeholder
|
||||
:on-change on-change*}]))
|
||||
|
||||
(mf/defc reply-form
|
||||
[{:keys [thread] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
show-buttons? (mf/use-state false)
|
||||
(let [show-buttons? (mf/use-state false)
|
||||
content (mf/use-state "")
|
||||
|
||||
disabled? (or (fm/all-spaces? @content)
|
||||
@@ -123,54 +120,32 @@
|
||||
(fn []
|
||||
(st/emit! (dcm/add-comment thread @content))
|
||||
(on-cancel)))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :reply-form)}
|
||||
[:& resizing-textarea {:value @content
|
||||
:placeholder "Reply"
|
||||
:on-blur on-blur
|
||||
:on-focus on-focus
|
||||
:select-on-focus? false
|
||||
:on-ctrl-enter on-submit
|
||||
:on-change on-change}]
|
||||
(when (or @show-buttons? (seq @content))
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
[:input.btn-secondary
|
||||
{:type "button"
|
||||
:class (stl/css :cancel-btn)
|
||||
:value "Cancel"
|
||||
:on-click on-cancel}]
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:value "Post"
|
||||
:on-click on-submit
|
||||
:disabled disabled?}]])]
|
||||
|
||||
|
||||
[:div.reply-form
|
||||
[:& resizing-textarea {:value @content
|
||||
:placeholder "Reply"
|
||||
:on-blur on-blur
|
||||
:on-focus on-focus
|
||||
:on-ctrl-enter on-submit
|
||||
:on-change on-change}]
|
||||
(when (or @show-buttons? (seq @content))
|
||||
[:div.buttons
|
||||
[:input.btn-primary
|
||||
{:type "button"
|
||||
:value "Post"
|
||||
:on-click on-submit
|
||||
:disabled disabled?}]
|
||||
[:input.btn-secondary
|
||||
{:type "button"
|
||||
:value "Cancel"
|
||||
:on-click on-cancel}]])])))
|
||||
[:div {:class (stl/css :reply-form)}
|
||||
[:& resizing-textarea {:value @content
|
||||
:placeholder "Reply"
|
||||
:on-blur on-blur
|
||||
:on-focus on-focus
|
||||
:select-on-focus? false
|
||||
:on-ctrl-enter on-submit
|
||||
:on-change on-change}]
|
||||
(when (or @show-buttons? (seq @content))
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
[:input.btn-secondary
|
||||
{:type "button"
|
||||
:class (stl/css :cancel-btn)
|
||||
:value "Cancel"
|
||||
:on-click on-cancel}]
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:value "Post"
|
||||
:on-click on-submit
|
||||
:disabled disabled?}]])]))
|
||||
|
||||
(mf/defc draft-thread
|
||||
[{:keys [draft zoom on-cancel on-submit position-modifier]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
position (cond-> (:position draft)
|
||||
(let [position (cond-> (:position draft)
|
||||
(some? position-modifier)
|
||||
(gpt/transform position-modifier))
|
||||
content (:content draft)
|
||||
@@ -201,73 +176,42 @@
|
||||
(mf/deps draft)
|
||||
(partial on-submit draft))]
|
||||
|
||||
[:*
|
||||
[:div
|
||||
{:class (stl/css :floating-thread-bubble)
|
||||
:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
"?"]
|
||||
[:div {:class (stl/css :thread-content)
|
||||
:style {:top (str (- pos-y 24) "px")
|
||||
:left (str (+ pos-x 28) "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
[:div {:class (stl/css :reply-form)}
|
||||
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
||||
:value (or content "")
|
||||
:autofocus true
|
||||
:select-on-focus? false
|
||||
:on-esc on-esc
|
||||
:on-change on-change
|
||||
:on-ctrl-enter on-submit}]
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
|
||||
(if new-css-system
|
||||
[:*
|
||||
[:div
|
||||
{:class (stl/css :floating-thread-bubble)
|
||||
:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
"?"]
|
||||
[:div {:class (stl/css :thread-content)
|
||||
:style {:top (str (- pos-y 24) "px")
|
||||
:left (str (+ pos-x 28) "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
[:div {:class (stl/css :reply-form)}
|
||||
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
||||
:value (or content "")
|
||||
:autofocus true
|
||||
:select-on-focus? false
|
||||
:on-esc on-esc
|
||||
:on-change on-change
|
||||
:on-ctrl-enter on-submit}]
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
[:input {:on-click on-esc
|
||||
:class (stl/css :cancel-btn)
|
||||
:type "button"
|
||||
:value "Cancel"}]
|
||||
|
||||
[:input {:on-click on-esc
|
||||
:class (stl/css :cancel-btn)
|
||||
:type "button"
|
||||
:value "Cancel"}]
|
||||
|
||||
[:input {:on-click on-submit
|
||||
:type "button"
|
||||
:value "Post"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:disabled disabled?}]]]]]
|
||||
|
||||
[:*
|
||||
[:div.thread-bubble
|
||||
{:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
[:span "?"]]
|
||||
[:div.thread-content
|
||||
{:style {:top (str (- pos-y 14) "px")
|
||||
:left (str (+ pos-x 14) "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
[:div.reply-form
|
||||
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
|
||||
:value (or content "")
|
||||
:autofocus true
|
||||
:on-esc on-esc
|
||||
:on-ctrl-enter on-submit
|
||||
:on-change on-change}]
|
||||
[:div.buttons
|
||||
[:input.btn-primary
|
||||
{:on-click on-submit
|
||||
:type "button"
|
||||
:value "Post"
|
||||
:disabled disabled?}]
|
||||
[:input.btn-secondary
|
||||
{:on-click on-esc
|
||||
:type "button"
|
||||
:value "Cancel"}]]]]])))
|
||||
[:input {:on-click on-submit
|
||||
:type "button"
|
||||
:value "Post"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:disabled disabled?}]]]]]))
|
||||
|
||||
(mf/defc edit-form
|
||||
[{:keys [content on-submit on-cancel] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
content (mf/use-state content)
|
||||
(let [content (mf/use-state content)
|
||||
|
||||
on-change
|
||||
(mf/use-fn
|
||||
@@ -281,44 +225,28 @@
|
||||
disabled? (or (fm/all-spaces? @content)
|
||||
(str/empty-or-nil? @content))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :edit-form)}
|
||||
[:& resizing-textarea {:value @content
|
||||
:autofocus true
|
||||
:select-on-focus true
|
||||
:select-on-focus? false
|
||||
:on-ctrl-enter on-submit*
|
||||
:on-change on-change}]
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
[:input {:type "button"
|
||||
:value "Cancel"
|
||||
:class (stl/css :cancel-btn)
|
||||
:on-click on-cancel}]
|
||||
[:input {:type "button"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:value "Post"
|
||||
:on-click on-submit*
|
||||
:disabled disabled?}]]]
|
||||
|
||||
|
||||
[:div.reply-form.edit-form
|
||||
[:& resizing-textarea {:value @content
|
||||
:autofocus true
|
||||
:select-on-focus true
|
||||
:on-ctrl-enter on-submit*
|
||||
:on-change on-change}]
|
||||
[:div.buttons
|
||||
[:input.btn-primary {:type "button"
|
||||
:value "Post"
|
||||
:on-click on-submit*
|
||||
:disabled disabled?}]
|
||||
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]])))
|
||||
[:div {:class (stl/css :edit-form)}
|
||||
[:& resizing-textarea {:value @content
|
||||
:autofocus true
|
||||
:select-on-focus true
|
||||
:select-on-focus? false
|
||||
:on-ctrl-enter on-submit*
|
||||
:on-change on-change}]
|
||||
[:div {:class (stl/css :buttons-wrapper)}
|
||||
[:input {:type "button"
|
||||
:value "Cancel"
|
||||
:class (stl/css :cancel-btn)
|
||||
:on-click on-cancel}]
|
||||
[:input {:type "button"
|
||||
:class (stl/css-case :post-btn true
|
||||
:global/disabled disabled?)
|
||||
:value "Post"
|
||||
:on-click on-submit*
|
||||
:disabled disabled?}]]]))
|
||||
|
||||
(mf/defc comment-item
|
||||
[{:keys [comment thread users origin] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
owner (get users (:owner-id comment))
|
||||
(let [owner (get users (:owner-id comment))
|
||||
profile (mf/deref refs/profile)
|
||||
options (mf/use-state false)
|
||||
edition? (mf/use-state false)
|
||||
@@ -382,82 +310,46 @@
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dcm/update-comment-thread (update thread :is-resolved not)))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :comment-container)}
|
||||
[:div {:class (stl/css :comment)}
|
||||
[:div {:class (stl/css :author)}
|
||||
[:div {:class (stl/css :avatar)}
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div {:class (stl/css :name)}
|
||||
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at comment))]]
|
||||
[:div {:class (stl/css :comment-container)}
|
||||
[:div {:class (stl/css :comment)}
|
||||
[:div {:class (stl/css :author)}
|
||||
[:div {:class (stl/css :avatar)}
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div {:class (stl/css :name)}
|
||||
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at comment))]]
|
||||
|
||||
(when (some? thread)
|
||||
[:div {:class (stl/css :options-resolve-wrapper)
|
||||
:on-click toggle-resolved}
|
||||
[:span {:class (stl/css-case :options-resolve true
|
||||
:global/checked (:is-resolved thread))} i/tick-refactor]])
|
||||
(when (some? thread)
|
||||
[:div {:class (stl/css :options-resolve-wrapper)
|
||||
:on-click toggle-resolved}
|
||||
[:span {:class (stl/css-case :options-resolve true
|
||||
:global/checked (:is-resolved thread))} i/tick-refactor]])
|
||||
|
||||
(when (= (:id profile) (:id owner))
|
||||
[:div {:class (stl/css :options)
|
||||
:on-click on-toggle-options}
|
||||
i/menu-refactor])]
|
||||
(when (= (:id profile) (:id owner))
|
||||
[:div {:class (stl/css :options)
|
||||
:on-click on-toggle-options}
|
||||
i/menu-refactor])]
|
||||
|
||||
[:div {:class (stl/css :content)}
|
||||
(if @edition?
|
||||
[:& edit-form {:content (:content comment)
|
||||
:on-submit on-submit
|
||||
:on-cancel on-cancel}]
|
||||
[:span {:class (stl/css :text)} (:content comment)])]]
|
||||
[:div {:class (stl/css :content)}
|
||||
(if @edition?
|
||||
[:& edit-form {:content (:content comment)
|
||||
:on-submit on-submit
|
||||
:on-cancel on-cancel}]
|
||||
[:span {:class (stl/css :text)} (:content comment)])]]
|
||||
|
||||
[:& dropdown {:show @options
|
||||
:on-close on-hide-options}
|
||||
[:ul {:class (stl/css :comment-options-dropdown)}
|
||||
[:& dropdown {:show @options
|
||||
:on-close on-hide-options}
|
||||
[:ul {:class (stl/css :comment-options-dropdown)}
|
||||
[:li {:class (stl/css :context-menu-option)
|
||||
:on-click on-edit-clicked}
|
||||
(tr "labels.edit")]
|
||||
(if thread
|
||||
[:li {:class (stl/css :context-menu-option)
|
||||
:on-click on-edit-clicked}
|
||||
(tr "labels.edit")]
|
||||
(if thread
|
||||
[:li {:class (stl/css :context-menu-option)
|
||||
:on-click on-delete-thread}
|
||||
(tr "labels.delete-comment-thread")]
|
||||
[:li {:class (stl/css :context-menu-option)
|
||||
:on-click on-delete-comment}
|
||||
(tr "labels.delete-comment")])]]]
|
||||
|
||||
|
||||
[:div.comment-container
|
||||
[:div.comment
|
||||
[:div.author
|
||||
[:div.avatar
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div.name
|
||||
[:div.fullname (:fullname owner)]
|
||||
[:div.timeago (dt/timeago (:modified-at comment))]]
|
||||
|
||||
(when (some? thread)
|
||||
[:div.options-resolve {:on-click toggle-resolved}
|
||||
(if (:is-resolved thread)
|
||||
[:span i/checkbox-checked]
|
||||
[:span i/checkbox-unchecked])])
|
||||
|
||||
(when (= (:id profile) (:id owner))
|
||||
[:div.options
|
||||
[:div.options-icon {:on-click on-toggle-options} i/actions]])]
|
||||
|
||||
[:div.content
|
||||
(if @edition?
|
||||
[:& edit-form {:content (:content comment)
|
||||
:on-submit on-submit
|
||||
:on-cancel on-cancel}]
|
||||
[:span.text (:content comment)])]]
|
||||
|
||||
[:& dropdown {:show @options
|
||||
:on-close on-hide-options}
|
||||
[:ul.dropdown.comment-options-dropdown
|
||||
[:li {:on-click on-edit-clicked} (tr "labels.edit")]
|
||||
(if thread
|
||||
[:li {:on-click on-delete-thread} (tr "labels.delete-comment-thread")]
|
||||
[:li {:on-click on-delete-comment} (tr "labels.delete-comment")])]]])))
|
||||
:on-click on-delete-thread}
|
||||
(tr "labels.delete-comment-thread")]
|
||||
[:li {:class (stl/css :context-menu-option)
|
||||
:on-click on-delete-comment}
|
||||
(tr "labels.delete-comment")])]]]))
|
||||
|
||||
(defn make-comments-ref
|
||||
[thread-id]
|
||||
@@ -466,8 +358,7 @@
|
||||
(mf/defc thread-comments
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [thread zoom users origin position-modifier]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
ref (mf/use-ref)
|
||||
(let [ref (mf/use-ref)
|
||||
|
||||
|
||||
thread-id (:id thread)
|
||||
@@ -477,12 +368,8 @@
|
||||
(some? position-modifier)
|
||||
(gpt/transform position-modifier))
|
||||
|
||||
pos-x (if new-css-system
|
||||
(+ (* (:x pos) zoom) 24)
|
||||
(+ (* (:x pos) zoom) 14))
|
||||
pos-y (if new-css-system
|
||||
(- (* (:y pos) zoom) 28)
|
||||
(- (* (:y pos) zoom) 14))
|
||||
pos-x (+ (* (:x pos) zoom) 24)
|
||||
pos-y (- (* (:y pos) zoom) 28)
|
||||
|
||||
|
||||
comments-ref (mf/with-memo [thread-id]
|
||||
@@ -504,46 +391,24 @@
|
||||
(mf/with-layout-effect [thread-pos comments-map]
|
||||
(when-let [node (mf/ref-val ref)]
|
||||
(dom/scroll-into-view-if-needed! node)))
|
||||
(if new-css-system
|
||||
(when (some? comment)
|
||||
[:div {:class (stl/css :thread-content)
|
||||
:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
(when (some? comment)
|
||||
[:div {:class (stl/css :thread-content)
|
||||
:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
|
||||
[:div {:class (stl/css :comments)}
|
||||
[:& comment-item {:comment comment
|
||||
:users users
|
||||
:thread thread
|
||||
:origin origin}]
|
||||
(for [item (rest comments)]
|
||||
[:* {:key (dm/str (:id item))}
|
||||
[:& comment-item {:comment item
|
||||
:users users
|
||||
:origin origin}]])
|
||||
[:div {:ref ref}]]
|
||||
[:& reply-form {:thread thread}]])
|
||||
|
||||
|
||||
(when (some? comment)
|
||||
[:div.thread-content
|
||||
{:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
|
||||
[:div.comments
|
||||
[:& comment-item {:comment comment
|
||||
:users users
|
||||
:thread thread
|
||||
:origin origin}]
|
||||
(for [item (rest comments)]
|
||||
[:* {:key (dm/str (:id item))}
|
||||
[:hr]
|
||||
[:& comment-item {:comment item
|
||||
:users users
|
||||
:origin origin}]])
|
||||
[:div {:ref ref}]]
|
||||
[:& reply-form {:thread thread}]]))))
|
||||
[:div {:class (stl/css :comments)}
|
||||
[:& comment-item {:comment comment
|
||||
:users users
|
||||
:thread thread
|
||||
:origin origin}]
|
||||
(for [item (rest comments)]
|
||||
[:* {:key (dm/str (:id item))}
|
||||
[:& comment-item {:comment item
|
||||
:users users
|
||||
:origin origin}]])
|
||||
[:div {:ref ref}]]
|
||||
[:& reply-form {:thread thread}]])))
|
||||
|
||||
(defn use-buble
|
||||
[zoom {:keys [position frame-id]}]
|
||||
@@ -602,8 +467,7 @@
|
||||
(mf/defc thread-bubble
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [thread zoom open? on-click origin position-modifier]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
pos (cond-> (:position thread)
|
||||
(let [pos (cond-> (:position thread)
|
||||
(some? position-modifier)
|
||||
(gpt/transform position-modifier))
|
||||
|
||||
@@ -658,37 +522,22 @@
|
||||
(dom/stop-propagation event)
|
||||
(when (= origin :viewer)
|
||||
(on-click thread))))]
|
||||
(if new-css-system
|
||||
[:div {:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-pointer-down on-pointer-down*
|
||||
:on-pointer-up on-pointer-up*
|
||||
:on-pointer-move on-pointer-move*
|
||||
:on-click on-click*
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:class (stl/css-case
|
||||
:floating-thread-bubble true
|
||||
:resolved (:is-resolved thread)
|
||||
:unread (pos? (:count-unread-comments thread)))}
|
||||
[:span (:seqn thread)]]
|
||||
|
||||
[:div.thread-bubble
|
||||
{:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-pointer-down on-pointer-down*
|
||||
:on-pointer-up on-pointer-up*
|
||||
:on-pointer-move on-pointer-move*
|
||||
:on-click on-click*
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:class (dom/classnames
|
||||
:resolved (:is-resolved thread)
|
||||
:unread (pos? (:count-unread-comments thread)))}
|
||||
[:span (:seqn thread)]])))
|
||||
[:div {:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-pointer-down on-pointer-down*
|
||||
:on-pointer-up on-pointer-up*
|
||||
:on-pointer-move on-pointer-move*
|
||||
:on-click on-click*
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:class (stl/css-case
|
||||
:floating-thread-bubble true
|
||||
:resolved (:is-resolved thread)
|
||||
:unread (pos? (:count-unread-comments thread)))}
|
||||
[:span (:seqn thread)]]))
|
||||
|
||||
(mf/defc comment-thread
|
||||
[{:keys [item users on-click]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
owner (get users (:owner-id item))
|
||||
(let [owner (get users (:owner-id item))
|
||||
on-click*
|
||||
(mf/use-fn
|
||||
(mf/deps item)
|
||||
@@ -698,99 +547,50 @@
|
||||
(when (fn? on-click)
|
||||
(on-click item))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :comment)
|
||||
:on-click on-click*}
|
||||
[:div {:class (stl/css :author)}
|
||||
[:div {:class (stl/css-case :thread-bubble true
|
||||
:resolved (:is-resolved item)
|
||||
:unread (pos? (:count-unread-comments item)))}
|
||||
(:seqn item)]
|
||||
[:div {:class (stl/css :avatar)}
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div {:class (stl/css :name)}
|
||||
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at item))]]]
|
||||
[:div {:class (stl/css :content)}
|
||||
(:content item)]
|
||||
[:div {:class (stl/css :replies)}
|
||||
(let [unread (:count-unread-comments item ::none)
|
||||
total (:count-comments item 1)]
|
||||
[:*
|
||||
(when (> total 1)
|
||||
(if (= total 2)
|
||||
[:span {:class (stl/css :total-replies)} "1 reply"]
|
||||
[:span {:class (stl/css :total-replies)} (str (dec total) " replies")]))
|
||||
[:div {:class (stl/css :comment)
|
||||
:on-click on-click*}
|
||||
[:div {:class (stl/css :author)}
|
||||
[:div {:class (stl/css-case :thread-bubble true
|
||||
:resolved (:is-resolved item)
|
||||
:unread (pos? (:count-unread-comments item)))}
|
||||
(:seqn item)]
|
||||
[:div {:class (stl/css :avatar)}
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div {:class (stl/css :name)}
|
||||
[:div {:class (stl/css :fullname)} (:fullname owner)]
|
||||
[:div {:class (stl/css :timeago)} (dt/timeago (:modified-at item))]]]
|
||||
[:div {:class (stl/css :content)}
|
||||
(:content item)]
|
||||
[:div {:class (stl/css :replies)}
|
||||
(let [unread (:count-unread-comments item ::none)
|
||||
total (:count-comments item 1)]
|
||||
[:*
|
||||
(when (> total 1)
|
||||
(if (= total 2)
|
||||
[:span {:class (stl/css :total-replies)} "1 reply"]
|
||||
[:span {:class (stl/css :total-replies)} (str (dec total) " replies")]))
|
||||
|
||||
(when (and (> total 1) (> unread 0))
|
||||
(if (= unread 1)
|
||||
[:span {:class (stl/css :new-replies)} "1 new reply"]
|
||||
[:span {:class (stl/css :new-replies)} (str unread " new replies")]))])]]
|
||||
|
||||
|
||||
[:div.comment {:on-click on-click*}
|
||||
[:div.author
|
||||
[:div.thread-bubble
|
||||
{:class (dom/classnames
|
||||
:resolved (:is-resolved item)
|
||||
:unread (pos? (:count-unread-comments item)))}
|
||||
(:seqn item)]
|
||||
[:div.avatar
|
||||
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
|
||||
[:div.name
|
||||
[:div.fullname (:fullname owner) ", "]
|
||||
[:div.timeago (dt/timeago (:modified-at item))]]]
|
||||
[:div.content
|
||||
[:span.text (:content item)]]
|
||||
[:div.content.replies
|
||||
(let [unread (:count-unread-comments item ::none)
|
||||
total (:count-comments item 1)]
|
||||
[:*
|
||||
(when (> total 1)
|
||||
(if (= total 2)
|
||||
[:span.total-replies "1 reply"]
|
||||
[:span.total-replies (str (dec total) " replies")]))
|
||||
|
||||
(when (and (> total 1) (> unread 0))
|
||||
(if (= unread 1)
|
||||
[:span.new-replies "1 new reply"]
|
||||
[:span.new-replies (str unread " new replies")]))])]])))
|
||||
(when (and (> total 1) (> unread 0))
|
||||
(if (= unread 1)
|
||||
[:span {:class (stl/css :new-replies)} "1 new reply"]
|
||||
[:span {:class (stl/css :new-replies)} (str unread " new replies")]))])]]))
|
||||
|
||||
(mf/defc comment-thread-group
|
||||
[{:keys [group users on-thread-click]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :thread-group)}
|
||||
(if (:file-name group)
|
||||
[:div {:class (stl/css :section-title)}
|
||||
[:span {:class (stl/css :file-name)} (:file-name group) ", "]
|
||||
[:span {:class (stl/css :page-name)} (:page-name group)]]
|
||||
[:div {:class (stl/css :thread-group)}
|
||||
(if (:file-name group)
|
||||
[:div {:class (stl/css :section-title)}
|
||||
[:span {:class (stl/css :file-name)} (:file-name group) ", "]
|
||||
[:span {:class (stl/css :page-name)} (:page-name group)]]
|
||||
|
||||
[:div {:class (stl/css :section-title)}
|
||||
[:span {:class (stl/css :icon)} i/document-refactor]
|
||||
[:span {:class (stl/css :page-name)} (:page-name group)]])
|
||||
[:div {:class (stl/css :section-title)}
|
||||
[:span {:class (stl/css :icon)} i/document-refactor]
|
||||
[:span {:class (stl/css :page-name)} (:page-name group)]])
|
||||
|
||||
[:div {:class (stl/css :threads)}
|
||||
(for [item (:items group)]
|
||||
[:& comment-thread
|
||||
{:item item
|
||||
:on-click on-thread-click
|
||||
:users users
|
||||
:key (:id item)}])]]
|
||||
|
||||
|
||||
[:div.thread-group
|
||||
(if (:file-name group)
|
||||
[:div.section-title
|
||||
[:span.label.filename (:file-name group) ", "]
|
||||
[:span.label (:page-name group)]]
|
||||
[:div.section-title
|
||||
[:span.icon i/file-html]
|
||||
[:span.label (:page-name group)]])
|
||||
[:div.threads
|
||||
(for [item (:items group)]
|
||||
[:& comment-thread
|
||||
{:item item
|
||||
:on-click on-thread-click
|
||||
:users users
|
||||
:key (:id item)}])]])))
|
||||
[:div {:class (stl/css :threads)}
|
||||
(for [item (:items group)]
|
||||
[:& comment-thread
|
||||
{:item item
|
||||
:on-click on-thread-click
|
||||
:users users
|
||||
:key (:id item)}])]])
|
||||
|
||||
@@ -13,96 +13,106 @@
|
||||
border-radius: $br-8;
|
||||
padding: $s-8 $s-16;
|
||||
|
||||
.section-title {
|
||||
@include titleTipography;
|
||||
height: $s-32;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $s-8;
|
||||
.file-name {
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
.page-name {
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 $s-6 0 $s-4;
|
||||
width: $s-24;
|
||||
height: $s-32;
|
||||
margin-left: $s-6;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
.threads {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-24;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $db-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@include titleTipography;
|
||||
height: $s-32;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $s-8;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
|
||||
.page-name {
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 $s-6 0 $s-4;
|
||||
width: $s-24;
|
||||
height: $s-32;
|
||||
margin-left: $s-6;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.threads {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-24;
|
||||
}
|
||||
|
||||
// Comment-thread
|
||||
.comment {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-12;
|
||||
.author {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
.thread-bubble {
|
||||
@extend .comment-bubbles;
|
||||
&.resolved {
|
||||
@extend .resolved-comment-bubble;
|
||||
}
|
||||
&.unread {
|
||||
@extend .unread-comment-bubble;
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-circle;
|
||||
img {
|
||||
border-radius: $br-circle;
|
||||
}
|
||||
}
|
||||
.name {
|
||||
flex-grow: 1;
|
||||
.fullname {
|
||||
@include textEllipsis;
|
||||
color: var(--comment-title-color);
|
||||
}
|
||||
.timeago {
|
||||
@include textEllipsis;
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.author {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.thread-bubble {
|
||||
@extend .comment-bubbles;
|
||||
&.resolved {
|
||||
@extend .resolved-comment-bubble;
|
||||
}
|
||||
.content {
|
||||
@include titleTipography;
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
.replies {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
.total-replies {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
.new-replies {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
&.unread {
|
||||
@extend .unread-comment-bubble;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-circle;
|
||||
img {
|
||||
border-radius: $br-circle;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
flex-grow: 1;
|
||||
.fullname {
|
||||
@include textEllipsis;
|
||||
color: var(--comment-title-color);
|
||||
}
|
||||
.timeago {
|
||||
@include textEllipsis;
|
||||
color: var(--comment-subtitle-color);
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
@include titleTipography;
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.replies {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.total-replies {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
.new-replies {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
// Thread-bubble
|
||||
|
||||
.floating-thread-bubble {
|
||||
|
||||
@@ -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]))
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -30,15 +30,14 @@
|
||||
(when label-text
|
||||
[:label {:for input-id :class-name label-class} label-text])
|
||||
|
||||
[:input
|
||||
{:style {:display "none"
|
||||
:width 0}
|
||||
:id input-id
|
||||
:multiple multi
|
||||
:accept accept
|
||||
:type "file"
|
||||
:ref input-ref
|
||||
:on-change on-files-selected
|
||||
:data-test data-test
|
||||
:aria-label "uploader"}]]))
|
||||
[:input {:style {:display "none"
|
||||
:width 0}
|
||||
:id input-id
|
||||
:multiple multi
|
||||
:accept accept
|
||||
:type "file"
|
||||
:ref input-ref
|
||||
:on-change on-files-selected
|
||||
:data-test data-test
|
||||
:aria-label "uploader"}]]))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
(:require
|
||||
[app.main.data.modal :as modal]
|
||||
[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 :as i18n :refer [tr t]]
|
||||
@@ -31,8 +30,7 @@
|
||||
cancel-label
|
||||
accept-label
|
||||
accept-style] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
locale (mf/deref i18n/locale)
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
|
||||
on-accept (or on-accept identity)
|
||||
on-cancel (or on-cancel identity)
|
||||
@@ -67,87 +65,45 @@
|
||||
(partial events/unlistenByKey))))
|
||||
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click cancel-fn} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click cancel-fn} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 {:class (stl/css :modal-msg)} message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-message])
|
||||
(when (string? hint)
|
||||
[:p {:class (stl/css :modal-hint)} hint])
|
||||
(when (> (count items) 0)
|
||||
[:*
|
||||
[:p {:class (stl/css :modal-subtitle)}
|
||||
(tr "ds.component-subtitle")]
|
||||
[:ul {:class (stl/css :component-list)}
|
||||
(for [item items]
|
||||
[:li {:class (stl/css :modal-item-element)}
|
||||
[:span {:class (stl/css :modal-component-icon)}
|
||||
i/component-refactor]
|
||||
[:span {:class (stl/css :modal-component-name)}
|
||||
(:name item)]])]])]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input
|
||||
{:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 {:class (stl/css :modal-msg)} message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-message])
|
||||
(when (string? hint)
|
||||
[:p {:class (stl/css :modal-hint)} hint])
|
||||
(when (> (count items) 0)
|
||||
[:*
|
||||
[:p {:class (stl/css :modal-subtitle)}
|
||||
(tr "ds.component-subtitle")]
|
||||
[:ul {:class (stl/css :component-list)}
|
||||
(for [item items]
|
||||
[:li {:class (stl/css :modal-item-element)}
|
||||
[:span {:class (stl/css :modal-component-icon)}
|
||||
i/component-refactor]
|
||||
[:span {:class (stl/css :modal-component-name)}
|
||||
(:name item)]])]])]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input
|
||||
{:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
{:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.confirm-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 title]]
|
||||
[:div.modal-close-button
|
||||
{:on-click cancel-fn} i/close]]
|
||||
|
||||
[:div.modal-content
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 message])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 scd-message])
|
||||
(when (string? hint)
|
||||
[:p hint])
|
||||
(when (> (count items) 0)
|
||||
[:*
|
||||
[:p (tr "ds.component-subtitle")]
|
||||
[:ul.component-list
|
||||
(for [item items]
|
||||
[:li.modal-item-element
|
||||
[:span.modal-component-icon i/component]
|
||||
[:span (:name item)]])]])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
|
||||
[:input.accept-button
|
||||
{:class (dom/classnames
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]])))
|
||||
[:input
|
||||
{:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]))
|
||||
|
||||
@@ -11,56 +11,63 @@
|
||||
&.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.component-list {
|
||||
.modal-item-element {
|
||||
@include flexRow;
|
||||
.modal-component-icon {
|
||||
@include flexCenter;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--color);
|
||||
}
|
||||
}
|
||||
.modal-component-name {
|
||||
@include titleTipography;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-hint {
|
||||
@extend .modal-hint-base;
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
}
|
||||
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.modal-item-element {
|
||||
@include flexRow;
|
||||
}
|
||||
|
||||
.modal-component-icon {
|
||||
@include flexCenter;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--color);
|
||||
}
|
||||
}
|
||||
.modal-component-name {
|
||||
@include titleTipography;
|
||||
}
|
||||
|
||||
.modal-hint {
|
||||
@extend .modal-hint-base;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}])])]]))
|
||||
|
||||
|
||||
@@ -12,7 +12,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.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
@@ -26,8 +25,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :leave-and-reassign}
|
||||
[{:keys [profile team accept]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
form (fm/use-form :spec ::leave-modal-form :initial {})
|
||||
(let [form (fm/use-form :spec ::leave-modal-form :initial {})
|
||||
members-map (mf/deref refs/dashboard-team-members)
|
||||
members (vals members-map)
|
||||
|
||||
@@ -42,71 +40,37 @@
|
||||
(let [member-id (get-in @form [:clean-data :member-id])]
|
||||
(accept member-id)))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.leave-and-reassign.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-cancel} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.leave-and-reassign.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-cancel} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:p {:class (stl/css :modal-msg)}
|
||||
(tr "modals.leave-and-reassign.hint1" (:name team))]
|
||||
|
||||
(if (empty? members)
|
||||
[:p {:class (stl/css :modal-msg)}
|
||||
(tr "modals.leave-and-reassign.hint1" (:name team))]
|
||||
(tr "modals.leave-and-reassign.forbidden")]
|
||||
[:*
|
||||
[:& fm/form {:form form}
|
||||
[:& fm/select {:name :member-id
|
||||
:options options}]]])]
|
||||
|
||||
(if (empty? members)
|
||||
[:p {:class (stl/css :modal-msg)}
|
||||
(tr "modals.leave-and-reassign.forbidden")]
|
||||
[:*
|
||||
[:& fm/form {:form form}
|
||||
[:& fm/select {:name :member-id
|
||||
:options options}]]])]
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
|
||||
[:input.accept-button
|
||||
{:type "button"
|
||||
:class (stl/css-case :accept-btn true
|
||||
:danger (:valid @form)
|
||||
:global/disabled (not (:valid @form)))
|
||||
:disabled (not (:valid @form))
|
||||
:value (tr "modals.leave-and-reassign.promote-and-leave")
|
||||
:on-click on-accept}]]]]]
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.confirm-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (tr "modals.leave-and-reassign.title")]]
|
||||
[:div.modal-close-button
|
||||
{:on-click on-cancel} i/close]]
|
||||
|
||||
[:div.modal-content.generic-form
|
||||
[:p (tr "modals.leave-and-reassign.hint1" (:name team))]
|
||||
|
||||
(if (empty? members)
|
||||
[:p (tr "modals.leave-and-reassign.forbidden")]
|
||||
[:*
|
||||
[:& fm/form {:form form}
|
||||
[:& fm/select {:name :member-id
|
||||
:options options}]]])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
|
||||
[:input.accept-button
|
||||
{:type "button"
|
||||
:class (if (:valid @form) "danger" "btn-disabled")
|
||||
:disabled (not (:valid @form))
|
||||
:value (tr "modals.leave-and-reassign.promote-and-leave")
|
||||
:on-click on-accept}]]]]])))
|
||||
[:input.accept-button
|
||||
{:type "button"
|
||||
:class (stl/css-case :accept-btn true
|
||||
:danger (:valid @form)
|
||||
:global/disabled (not (:valid @form)))
|
||||
:disabled (not (:valid @form))
|
||||
:value (tr "modals.leave-and-reassign.promote-and-leave")
|
||||
:on-click on-accept}]]]]]))
|
||||
|
||||
@@ -8,39 +8,46 @@
|
||||
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")])]]]))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.worker :as uw]
|
||||
[app.util.dom :as dom]
|
||||
@@ -24,36 +23,19 @@
|
||||
(mf/defc export-entry
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
[:div {:class (stl/css-case :file-entry true
|
||||
:loading (:loading? file)
|
||||
:success (:export-success? file)
|
||||
:error (:export-error? file))}
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css-case :file-entry true
|
||||
:loading (:loading? file)
|
||||
:success (:export-success? file)
|
||||
:error (:export-error? file))}
|
||||
[:div {:class (stl/css :file-name)}
|
||||
[:span {:class (stl/css :file-icon)}
|
||||
(cond (:export-success? file) i/tick-refactor
|
||||
(:export-error? file) i/close-refactor
|
||||
(:loading? file) i/loader-pencil)]
|
||||
|
||||
[:div {:class (stl/css :file-name)}
|
||||
[:span {:class (stl/css :file-icon)}
|
||||
(cond (:export-success? file) i/tick-refactor
|
||||
(:export-error? file) i/close-refactor
|
||||
(:loading? file) i/loader-pencil)]
|
||||
|
||||
[:div {:class (stl/css :file-name-label)}
|
||||
(:name file)]]]
|
||||
|
||||
|
||||
[:div.file-entry
|
||||
{:class (dom/classnames
|
||||
:loading (:loading? file)
|
||||
:success (:export-success? file)
|
||||
:error (:export-error? file))}
|
||||
[:div.file-name
|
||||
[:div.file-icon
|
||||
(cond (:export-success? file) i/tick
|
||||
(:export-error? file) i/close
|
||||
(:loading? file) i/loader-pencil)]
|
||||
|
||||
[:div.file-name-label (:name file)]]])))
|
||||
[:div {:class (stl/css :file-name-label)}
|
||||
(:name file)]]])
|
||||
|
||||
(defn- mark-file-error
|
||||
[files file-id]
|
||||
@@ -79,8 +61,7 @@
|
||||
::mf/register-as :export
|
||||
::mf/wrap-props false}
|
||||
[{:keys [team-id files has-libraries? binary? features]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
state* (mf/use-state
|
||||
(let [state* (mf/use-state
|
||||
#(let [files (mapv (fn [file] (assoc file :loading? true)) files)]
|
||||
{:status :prepare
|
||||
:selected :all
|
||||
@@ -140,136 +121,70 @@
|
||||
(when-not has-libraries?
|
||||
(start-export)))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "dashboard.export.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-cancel} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "dashboard.export.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-cancel} i/close-refactor]]
|
||||
|
||||
(cond
|
||||
(= status :prepare)
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:p {:class (stl/css :modal-msg)} (tr "dashboard.export.explain")]
|
||||
[:p {:class (stl/css :modal-scd-msg)} (tr "dashboard.export.detail")]
|
||||
(cond
|
||||
(= status :prepare)
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:p {:class (stl/css :modal-msg)} (tr "dashboard.export.explain")]
|
||||
[:p {:class (stl/css :modal-scd-msg)} (tr "dashboard.export.detail")]
|
||||
|
||||
(for [type export-types]
|
||||
[:div {:class (stl/css :export-option true)
|
||||
:key (name type)}
|
||||
[:label {:for (str "export-" type)
|
||||
:class (stl/css-case :global/checked (= selected type))}
|
||||
;; Execution time translation strings:
|
||||
;; dashboard.export.options.all.message
|
||||
;; dashboard.export.options.all.title
|
||||
;; dashboard.export.options.detach.message
|
||||
;; dashboard.export.options.detach.title
|
||||
;; dashboard.export.options.merge.message
|
||||
;; dashboard.export.options.merge.title
|
||||
[:span {:class (stl/css-case :global/checked (= selected type))}
|
||||
(when (= selected type)
|
||||
i/status-tick-refactor)]
|
||||
[:div {:class (stl/css :option-content)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
|
||||
[:p {:class (stl/css :modal-msg)} (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]]
|
||||
(for [type export-types]
|
||||
[:div {:class (stl/css :export-option true)
|
||||
:key (name type)}
|
||||
[:label {:for (str "export-" type)
|
||||
:class (stl/css-case :global/checked (= selected type))}
|
||||
;; Execution time translation strings:
|
||||
;; dashboard.export.options.all.message
|
||||
;; dashboard.export.options.all.title
|
||||
;; dashboard.export.options.detach.message
|
||||
;; dashboard.export.options.detach.title
|
||||
;; dashboard.export.options.merge.message
|
||||
;; dashboard.export.options.merge.title
|
||||
[:span {:class (stl/css-case :global/checked (= selected type))}
|
||||
(when (= selected type)
|
||||
i/status-tick-refactor)]
|
||||
[:div {:class (stl/css :option-content)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
|
||||
[:p {:class (stl/css :modal-msg)} (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]]
|
||||
|
||||
[:input {:type "radio"
|
||||
:class (stl/css :option-input)
|
||||
:id (str "export-" type)
|
||||
:checked (= selected type)
|
||||
:name "export-option"
|
||||
:data-type (name type)
|
||||
:on-change on-change}]]])]
|
||||
[:input {:type "radio"
|
||||
:class (stl/css :option-input)
|
||||
:id (str "export-" type)
|
||||
:checked (= selected type)
|
||||
:name "export-option"
|
||||
:data-type (name type)
|
||||
:on-change on-change}]]])]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:on-click on-accept}]]]]
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:on-click on-accept}]]]]
|
||||
|
||||
(= status :exporting)
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(for [file (:files state)]
|
||||
[:& export-entry {:file file :key (dm/str (:id file))}])]
|
||||
(= status :exporting)
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(for [file (:files state)]
|
||||
[:& export-entry {:file file :key (dm/str (:id file))}])]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.close")
|
||||
:disabled (->> state :files (some :loading?))
|
||||
:on-click on-cancel}]]]])]]
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.export-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (tr "dashboard.export.title")]]
|
||||
|
||||
[:div.modal-close-button
|
||||
{:on-click on-cancel} i/close]]
|
||||
|
||||
(cond
|
||||
(= status :prepare)
|
||||
[:*
|
||||
[:div.modal-content
|
||||
[:p.explain (tr "dashboard.export.explain")]
|
||||
[:p.detail (tr "dashboard.export.detail")]
|
||||
|
||||
(for [type export-types]
|
||||
[:div.export-option {:class (when (= selected type) "selected")
|
||||
:key (name type)}
|
||||
[:label.option-container
|
||||
;; Execution time translation strings:
|
||||
;; dashboard.export.options.all.message
|
||||
;; dashboard.export.options.all.title
|
||||
;; dashboard.export.options.detach.message
|
||||
;; dashboard.export.options.detach.title
|
||||
;; dashboard.export.options.merge.message
|
||||
;; dashboard.export.options.merge.title
|
||||
[:h3 (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
|
||||
[:p (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]
|
||||
[:input {:type "radio"
|
||||
:checked (= selected type)
|
||||
:data-type (name type)
|
||||
:on-change on-change
|
||||
:name "export-option"}]
|
||||
[:span {:class "option-radio-check"}]]])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-cancel}]
|
||||
|
||||
[:input.accept-button
|
||||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:on-click on-accept}]]]]
|
||||
|
||||
(= status :exporting)
|
||||
[:*
|
||||
[:div.modal-content
|
||||
(for [file (:files state)]
|
||||
[:& export-entry {:file file :key (dm/str (:id file))}])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:input.accept-button
|
||||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.close")
|
||||
:disabled (->> state :files (some :loading?))
|
||||
:on-click on-cancel}]]]])]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.close")
|
||||
:disabled (->> state :files (some :loading?))
|
||||
:on-click on-cancel}]]]])]]))
|
||||
|
||||
@@ -8,59 +8,64 @@
|
||||
|
||||
.modal-overlay {
|
||||
@extend .modal-overlay-base;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
.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-container {
|
||||
@extend .modal-container-base;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.export-option {
|
||||
@extend .input-checkbox;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
label {
|
||||
align-items: flex-start;
|
||||
.modal-subtitle {
|
||||
@include tabTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
}
|
||||
span {
|
||||
margin-top: $s-8;
|
||||
}
|
||||
.option-content {
|
||||
@include flexColumn;
|
||||
@include titleTipography;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-header {
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-title {
|
||||
@include tabTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.modal-close-btn {
|
||||
@extend .modal-close-btn-base;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.export-option {
|
||||
@extend .input-checkbox;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
label {
|
||||
align-items: flex-start;
|
||||
.modal-subtitle {
|
||||
@include tabTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
}
|
||||
span {
|
||||
margin-top: $s-8;
|
||||
}
|
||||
}
|
||||
|
||||
.option-content {
|
||||
@include flexColumn;
|
||||
@include titleTipography;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-scd-msg,
|
||||
|
||||
@@ -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}]]]))
|
||||
|
||||
|
||||
@@ -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"]]])
|
||||
|
||||
|
||||
|
||||
@@ -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}])]))
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
[app.main.features :as features]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.worker :as uw]
|
||||
[app.util.dom :as dom]
|
||||
@@ -152,8 +151,7 @@
|
||||
(mf/defc import-entry
|
||||
[{:keys [state file editing? can-be-deleted?]}]
|
||||
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
loading? (or (= :analyzing (:status file))
|
||||
(let [loading? (or (= :analyzing (:status file))
|
||||
(= :importing (:status file)))
|
||||
analyze-error? (= :analyze-error (:status file))
|
||||
import-finish? (= :import-finish (:status file))
|
||||
@@ -191,122 +189,66 @@
|
||||
(fn []
|
||||
(swap! state update :files remove-file (:file-id file))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css-case :file-entry true
|
||||
:loading loading?
|
||||
:success (and import-finish? (not import-warn?) (not import-error?))
|
||||
:warning (and import-finish? import-warn? (not import-error?))
|
||||
:error (or import-error? analyze-error?)
|
||||
:editable (and ready? (not editing?)))}
|
||||
[:div {:class (stl/css-case :file-entry true
|
||||
:loading loading?
|
||||
:success (and import-finish? (not import-warn?) (not import-error?))
|
||||
:warning (and import-finish? import-warn? (not import-error?))
|
||||
:error (or import-error? analyze-error?)
|
||||
:editable (and ready? (not editing?)))}
|
||||
|
||||
[:div {:class (stl/css :file-name)}
|
||||
[:div {:class (stl/css-case :file-icon true
|
||||
:icon-fill ready?)}
|
||||
(cond loading? i/loader-pencil
|
||||
ready? i/logo-icon
|
||||
import-warn? i/msg-warning
|
||||
import-error? i/close-refactor
|
||||
import-finish? i/tick-refactor
|
||||
analyze-error? i/close-refactor)]
|
||||
[:div {:class (stl/css :file-name)}
|
||||
[:div {:class (stl/css-case :file-icon true
|
||||
:icon-fill ready?)}
|
||||
(cond loading? i/loader-pencil
|
||||
ready? i/logo-icon
|
||||
import-warn? i/msg-warning
|
||||
import-error? i/close-refactor
|
||||
import-finish? i/tick-refactor
|
||||
analyze-error? i/close-refactor)]
|
||||
|
||||
(if editing?
|
||||
[:div {:class (stl/css :file-name-edit)}
|
||||
[:input {:type "text"
|
||||
:auto-focus true
|
||||
:default-value (:name file)
|
||||
:on-key-press handle-edit-key-press
|
||||
:on-blur handle-edit-blur}]]
|
||||
(if editing?
|
||||
[:div {:class (stl/css :file-name-edit)}
|
||||
[:input {:type "text"
|
||||
:auto-focus true
|
||||
:default-value (:name file)
|
||||
:on-key-press handle-edit-key-press
|
||||
:on-blur handle-edit-blur}]]
|
||||
|
||||
[:div {:class (stl/css :file-name-label)}
|
||||
(:name file)
|
||||
(when is-shared? i/library-refactor)])
|
||||
[:div {:class (stl/css :file-name-label)}
|
||||
(:name file)
|
||||
(when is-shared? i/library-refactor)])
|
||||
|
||||
[:div {:class (stl/css :edit-entry-buttons)}
|
||||
(when (= "application/zip" (:type file))
|
||||
[:button {:on-click handle-edit-entry} i/curve-refactor])
|
||||
(when can-be-deleted?
|
||||
[:button {:on-click handle-remove-entry} i/delete-refactor])]]
|
||||
(cond
|
||||
analyze-error?
|
||||
[:div {:class (stl/css :error-message)}
|
||||
(tr "dashboard.import.analyze-error")]
|
||||
[:div {:class (stl/css :edit-entry-buttons)}
|
||||
(when (= "application/zip" (:type file))
|
||||
[:button {:on-click handle-edit-entry} i/curve-refactor])
|
||||
(when can-be-deleted?
|
||||
[:button {:on-click handle-remove-entry} i/delete-refactor])]]
|
||||
(cond
|
||||
analyze-error?
|
||||
[:div {:class (stl/css :error-message)}
|
||||
(tr "dashboard.import.analyze-error")]
|
||||
|
||||
import-error?
|
||||
[:div {:class (stl/css :error-message)}
|
||||
(tr "dashboard.import.import-error")]
|
||||
import-error?
|
||||
[:div {:class (stl/css :error-message)}
|
||||
(tr "dashboard.import.import-error")]
|
||||
|
||||
(and (not import-finish?) (some? progress))
|
||||
[:div {:class (stl/css :progress-message)} (parse-progress-message progress)])
|
||||
(and (not import-finish?) (some? progress))
|
||||
[:div {:class (stl/css :progress-message)} (parse-progress-message progress)])
|
||||
|
||||
[:div {:class (stl/css :linked-libraries)}
|
||||
(for [library-id (:libraries file)]
|
||||
(let [library-data (->> @state :files (d/seek #(= library-id (:file-id %))))
|
||||
error? (or (:deleted? library-data) (:import-error library-data))]
|
||||
(when (some? library-data)
|
||||
[:div {:class (stl/css-case :linked-library-tag true
|
||||
:error error?)}
|
||||
i/detach-refactor (:name library-data)])))]]
|
||||
|
||||
|
||||
[:div.file-entry
|
||||
{:class (dom/classnames
|
||||
:loading loading?
|
||||
:success (and import-finish? (not import-warn?) (not import-error?))
|
||||
:warning (and import-finish? import-warn? (not import-error?))
|
||||
:error (or import-error? analyze-error?)
|
||||
:editable (and ready? (not editing?)))}
|
||||
|
||||
[:div.file-name
|
||||
[:div.file-icon
|
||||
(cond loading? i/loader-pencil
|
||||
ready? i/logo-icon
|
||||
import-warn? i/msg-warning
|
||||
import-error? i/close
|
||||
import-finish? i/tick
|
||||
analyze-error? i/close)]
|
||||
|
||||
(if editing?
|
||||
[:div.file-name-edit
|
||||
[:input {:type "text"
|
||||
:auto-focus true
|
||||
:default-value (:name file)
|
||||
:on-key-press handle-edit-key-press
|
||||
:on-blur handle-edit-blur}]]
|
||||
|
||||
[:div.file-name-label (:name file) (when is-shared? i/library)])
|
||||
|
||||
[:div.edit-entry-buttons
|
||||
(when (= "application/zip" (:type file))
|
||||
[:button {:on-click handle-edit-entry} i/pencil])
|
||||
(when can-be-deleted?
|
||||
[:button {:on-click handle-remove-entry} i/trash])]]
|
||||
|
||||
(cond
|
||||
analyze-error?
|
||||
[:div.error-message
|
||||
(tr "dashboard.import.analyze-error")]
|
||||
|
||||
import-error?
|
||||
[:div.error-message
|
||||
(tr "dashboard.import.import-error")]
|
||||
|
||||
(and (not import-finish?) (some? progress))
|
||||
[:div.progress-message (parse-progress-message progress)])
|
||||
|
||||
[:div.linked-libraries
|
||||
(for [library-id (:libraries file)]
|
||||
(let [library-data (->> @state :files (d/seek #(= library-id (:file-id %))))
|
||||
error? (or (:deleted? library-data) (:import-error library-data))]
|
||||
(when (some? library-data)
|
||||
[:div.linked-library-tag {:class (when error? "error")}
|
||||
(if error? i/unchain i/chain) (:name library-data)])))]])))
|
||||
[:div {:class (stl/css :linked-libraries)}
|
||||
(for [library-id (:libraries file)]
|
||||
(let [library-data (->> @state :files (d/seek #(= library-id (:file-id %))))
|
||||
error? (or (:deleted? library-data) (:import-error library-data))]
|
||||
(when (some? library-data)
|
||||
[:div {:class (stl/css-case :linked-library-tag true
|
||||
:error error?)}
|
||||
i/detach-refactor (:name library-data)])))]]))
|
||||
|
||||
(mf/defc import-dialog
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :import}
|
||||
[{:keys [project-id files template on-finish-import]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
state (mf/use-state
|
||||
(let [state (mf/use-state
|
||||
{:status :analyzing
|
||||
:editing nil
|
||||
:importing-templates 0
|
||||
@@ -425,122 +367,60 @@
|
||||
#(doseq [file files]
|
||||
(wapi/revoke-uri (:uri file)))))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "dashboard.import")]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "dashboard.import")]
|
||||
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click handle-cancel} i/close-refactor]]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click handle-cancel} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
|
||||
(when (and (= :importing (:status @state)) (not pending-import?))
|
||||
(if (> warning-files 0)
|
||||
[:div {:class (stl/css-case :feedback-banner true
|
||||
:warning true)}
|
||||
[:div {:class (stl/css :icon)} i/msg-warning-refactor]
|
||||
[:div {:class (stl/css :message)} (tr "dashboard.import.import-warning" warning-files success-files)]]
|
||||
(when (and (= :importing (:status @state)) (not pending-import?))
|
||||
(if (> warning-files 0)
|
||||
[:div {:class (stl/css-case :feedback-banner true
|
||||
:warning true)}
|
||||
[:div {:class (stl/css :icon)} i/msg-warning-refactor]
|
||||
[:div {:class (stl/css :message)} (tr "dashboard.import.import-warning" warning-files success-files)]]
|
||||
|
||||
[:div {:class (stl/css :feedback-banner)}
|
||||
[:div {:class (stl/css :icon)} i/msg-success-refactor]
|
||||
[:div {:class (stl/css :message)} (tr "dashboard.import.import-message" (i18n/c (if (some? template) 1 success-files)))]]))
|
||||
[:div {:class (stl/css :feedback-banner)}
|
||||
[:div {:class (stl/css :icon)} i/msg-success-refactor]
|
||||
[:div {:class (stl/css :message)} (tr "dashboard.import.import-message" (i18n/c (if (some? template) 1 success-files)))]]))
|
||||
|
||||
(for [file files]
|
||||
(let [editing? (and (some? (:file-id file))
|
||||
(= (:file-id file) (:editing @state)))]
|
||||
[:& import-entry {:state state
|
||||
:key (dm/str (:uri file))
|
||||
:file file
|
||||
:editing? editing?
|
||||
:can-be-deleted? (> (count files) 1)}]))
|
||||
|
||||
(when (some? template)
|
||||
(for [file files]
|
||||
(let [editing? (and (some? (:file-id file))
|
||||
(= (:file-id file) (:editing @state)))]
|
||||
[:& import-entry {:state state
|
||||
:file (assoc template :status (if (= 1 (:importing-templates @state)) :importing :ready))
|
||||
:editing? false
|
||||
:can-be-deleted? false}])]
|
||||
:key (dm/str (:uri file))
|
||||
:file file
|
||||
:editing? editing?
|
||||
:can-be-deleted? (> (count files) 1)}]))
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click handle-cancel}])
|
||||
(when (some? template)
|
||||
[:& import-entry {:state state
|
||||
:file (assoc template :status (if (= 1 (:importing-templates @state)) :importing :ready))
|
||||
:editing? false
|
||||
:can-be-deleted? false}])]
|
||||
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:disabled (or pending-analysis? (not valid-files?))
|
||||
:on-click handle-continue}])
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click handle-cancel}])
|
||||
|
||||
(when (= :importing (:status @state))
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.accept")
|
||||
:disabled (or pending-import? (not valid-files?))
|
||||
:on-click handle-accept}])]]]]
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:disabled (or pending-analysis? (not valid-files?))
|
||||
:on-click handle-continue}])
|
||||
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.import-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (tr "dashboard.import")]]
|
||||
|
||||
[:div.modal-close-button
|
||||
{:on-click handle-cancel} i/close]]
|
||||
|
||||
[:div.modal-content
|
||||
(when (and (= :importing (:status @state)) (not pending-import?))
|
||||
(if (> warning-files 0)
|
||||
[:div.feedback-banner.warning
|
||||
[:div.icon i/msg-warning]
|
||||
[:div.message (tr "dashboard.import.import-warning" warning-files success-files)]]
|
||||
|
||||
[:div.feedback-banner
|
||||
[:div.icon i/checkbox-checked]
|
||||
[:div.message (tr "dashboard.import.import-message" (i18n/c (if (some? template) 1 success-files)))]]))
|
||||
|
||||
(for [file files]
|
||||
(let [editing? (and (some? (:file-id file))
|
||||
(= (:file-id file) (:editing @state)))]
|
||||
[:& import-entry {:state state
|
||||
:key (dm/str (:uri file))
|
||||
:file file
|
||||
:editing? editing?
|
||||
:can-be-deleted? (> (count files) 1)}]))
|
||||
|
||||
(when (some? template)
|
||||
[:& import-entry {:state state
|
||||
:file (assoc template :status (if (= 1 (:importing-templates @state)) :importing :ready))
|
||||
:editing? false
|
||||
:can-be-deleted? false}])]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click handle-cancel}])
|
||||
|
||||
(when (= :analyzing (:status @state))
|
||||
[:input.accept-button
|
||||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.continue")
|
||||
:disabled (or pending-analysis? (not valid-files?))
|
||||
:on-click handle-continue}])
|
||||
|
||||
(when (= :importing (:status @state))
|
||||
[:input.accept-button
|
||||
{:class "primary"
|
||||
:type "button"
|
||||
:value (tr "labels.accept")
|
||||
:disabled (or pending-import? (not valid-files?))
|
||||
:on-click handle-accept}])]]]])))
|
||||
(when (= :importing (:status @state))
|
||||
[:input {:class (stl/css :accept-btn)
|
||||
:type "button"
|
||||
:value (tr "labels.accept")
|
||||
:disabled (or pending-import? (not valid-files?))
|
||||
:on-click handle-accept}])]]]]))
|
||||
|
||||
122
frontend/src/app/main/ui/dashboard/import.scss
vendored
122
frontend/src/app/main/ui/dashboard/import.scss
vendored
@@ -8,69 +8,72 @@
|
||||
|
||||
.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-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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.feedback-banner {
|
||||
@include flexRow;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
margin-bottom: $s-24;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--alert-background-color-ok);
|
||||
color: var(--alert-foreground-color-ok);
|
||||
|
||||
.icon {
|
||||
@include flexCenter;
|
||||
height: $s-24;
|
||||
width: $s-24;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--alert-foreground-color-ok);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.feedback-banner {
|
||||
@include flexRow;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
margin-bottom: $s-24;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--alert-background-color-ok);
|
||||
color: var(--alert-foreground-color-ok);
|
||||
|
||||
.icon {
|
||||
@include flexCenter;
|
||||
height: $s-24;
|
||||
width: $s-24;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--alert-foreground-color-ok);
|
||||
}
|
||||
}
|
||||
.message {
|
||||
@include titleTipography;
|
||||
}
|
||||
&.warning {
|
||||
background-color: var(--alert-background-color-warning);
|
||||
color: var(--alert-foreground-color-warning);
|
||||
.icon svg {
|
||||
stroke: var(--alert-foreground-color-warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.message {
|
||||
@include titleTipography;
|
||||
}
|
||||
&.warning {
|
||||
background-color: var(--alert-background-color-warning);
|
||||
color: var(--alert-foreground-color-warning);
|
||||
.icon svg {
|
||||
stroke: var(--alert-foreground-color-warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +125,7 @@
|
||||
.error-message,
|
||||
.progress-message {
|
||||
height: $s-32;
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.linked-libraries {
|
||||
|
||||
@@ -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]]))
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}]]]))
|
||||
|
||||
|
||||
@@ -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")]])
|
||||
|
||||
@@ -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}]))]])))
|
||||
|
||||
@@ -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}])]]))
|
||||
|
||||
@@ -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}]]))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
@@ -70,73 +69,42 @@
|
||||
(mf/defc team-form-modal {::mf/register modal/components
|
||||
::mf/register-as :team-form}
|
||||
[{:keys [team] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
initial (mf/use-memo (fn [] (or team {})))
|
||||
(let [initial (mf/use-memo (fn [] (or team {})))
|
||||
form (fm/use-form :spec ::team-form
|
||||
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))]
|
||||
:initial initial)
|
||||
on-close #(st/emit! (modal/hide))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
(if team
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "labels.rename-team")]
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "labels.create-team")])
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
(if team
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "labels.rename-team")]
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "labels.create-team")])
|
||||
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:class (stl/css :group-name-input)
|
||||
:form form
|
||||
:name :name
|
||||
:placeholder "E.g. Design"
|
||||
:label (tr "labels.create-team.placeholder")}]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:class (stl/css :group-name-input)
|
||||
:form form
|
||||
:name :name
|
||||
:placeholder "E.g. Design"
|
||||
:label (tr "labels.create-team.placeholder")}]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:> fm/submit-button*
|
||||
{:label (if team
|
||||
(tr "labels.update-team")
|
||||
(tr "labels.create-team"))
|
||||
:className (stl/css :accept-btn)}]]]]]]
|
||||
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.team-form-modal
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
(if team
|
||||
[:h2 (tr "labels.rename-team")]
|
||||
[:h2 (tr "labels.create-team")])]
|
||||
|
||||
[:div.modal-close-button
|
||||
{:on-click #(st/emit! (modal/hide))} i/close]]
|
||||
|
||||
[:div.modal-content.generic-form
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:form form
|
||||
:name :name
|
||||
:label (tr "labels.create-team.placeholder")}]]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:> fm/submit-button*
|
||||
{:label (if team
|
||||
(tr "labels.update-team")
|
||||
(tr "labels.create-team"))}]]]]]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:> fm/submit-button*
|
||||
{:label (if team
|
||||
(tr "labels.update-team")
|
||||
(tr "labels.create-team"))
|
||||
:className (stl/css :accept-btn)}]]]]]]))
|
||||
|
||||
|
||||
|
||||
@@ -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])]))
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.repo :as rp]
|
||||
[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 :as i18n :refer [tr]]
|
||||
@@ -27,8 +26,7 @@
|
||||
::mf/register-as :delete-shared-libraries
|
||||
::mf/wrap-props false}
|
||||
[{:keys [ids on-accept on-cancel accept-style origin count-libraries]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
references* (mf/use-state {})
|
||||
(let [references* (mf/use-state {})
|
||||
references (deref references*)
|
||||
|
||||
on-accept (or on-accept noop)
|
||||
@@ -96,91 +94,43 @@
|
||||
(let [key (events/listen js/document "keydown" on-keydown)]
|
||||
(partial events/unlistenByKey key))))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click cancel-fn} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} title]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click cancel-fn} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? subtitle) (not= subtitle ""))
|
||||
[:h3 {:class (stl/css :modal-subtitle)} subtitle])
|
||||
(when (not= 0 count-libraries)
|
||||
(if (pos? (count references))
|
||||
[:*
|
||||
[:div
|
||||
(when (and (string? scd-msg) (not= scd-msg ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-msg])
|
||||
[:ul {:class (stl/css :element-list)}
|
||||
(for [[file-id file-name] references]
|
||||
[:li {:class (stl/css :list-item)
|
||||
:key (dm/str file-id)}
|
||||
[:span "- " file-name]])]]
|
||||
(when (and (string? hint) (not= hint ""))
|
||||
[:h3 {:class (stl/css :modal-hint)}hint])]
|
||||
[:*
|
||||
[:h3 {:class (stl/css :modal-msg)} no-files-msg]]))]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? subtitle) (not= subtitle ""))
|
||||
[:h3 {:class (stl/css :modal-subtitle)} subtitle])
|
||||
(when (not= 0 count-libraries)
|
||||
(if (pos? (count references))
|
||||
[:*
|
||||
[:div
|
||||
(when (and (string? scd-msg) (not= scd-msg ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-msg])
|
||||
[:ul {:class (stl/css :element-list)}
|
||||
(for [[file-id file-name] references]
|
||||
[:li {:class (stl/css :list-item)
|
||||
:key (dm/str file-id)}
|
||||
[:span "- " file-name]])]]
|
||||
(when (and (string? hint) (not= hint ""))
|
||||
[:h3 {:class (stl/css :modal-hint)} hint])]
|
||||
[:*
|
||||
[:h3 {:class (stl/css :modal-msg)} no-files-msg]]))]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
|
||||
[:input {:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.confirm-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 title]]
|
||||
[:div.modal-close-button
|
||||
{:on-click cancel-fn} i/close]]
|
||||
|
||||
[:div.modal-content.delete-shared
|
||||
(when (and (string? subtitle) (not= subtitle ""))
|
||||
[:h3 subtitle])
|
||||
(when (not= 0 count-libraries)
|
||||
(if (pos? (count references))
|
||||
[:*
|
||||
[:div
|
||||
(when (and (string? scd-msg) (not= scd-msg ""))
|
||||
[:h3 scd-msg])
|
||||
[:ul.file-list
|
||||
(for [[file-id file-name] references]
|
||||
[:li.modal-item-element
|
||||
{:key (dm/str file-id)}
|
||||
[:span "- " file-name]])]]
|
||||
(when (and (string? hint) (not= hint ""))
|
||||
[:h3 hint])]
|
||||
[:*
|
||||
[:h3 no-files-msg]]))]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
(when-not (= cancel-label :omit)
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value cancel-label
|
||||
:on-click cancel-fn}])
|
||||
|
||||
[:input.accept-button
|
||||
{:class (dom/classnames
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]
|
||||
)
|
||||
|
||||
))
|
||||
[:input {:class (stl/css-case :accept-btn true
|
||||
:danger (= accept-style :danger)
|
||||
:primary (= accept-style :primary))
|
||||
:type "button"
|
||||
:value accept-label
|
||||
:on-click accept-fn}]]]]]))
|
||||
|
||||
@@ -11,45 +11,53 @@
|
||||
&.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
.modal-hint {
|
||||
@extend .modal-hint-base;
|
||||
}
|
||||
.element-list {
|
||||
@include titleTipography;
|
||||
.list-item {
|
||||
@include titleTipography;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
}
|
||||
|
||||
.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 titleTipography;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.modal-hint {
|
||||
@extend .modal-hint-base;
|
||||
}
|
||||
|
||||
.element-list {
|
||||
@include titleTipography;
|
||||
.list-item {
|
||||
@include titleTipography;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,96 +14,52 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.link-button :as lb]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc banner
|
||||
[{:keys [type position status controls content links actions on-close data-test role] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css-case :banner true
|
||||
:warning (= type :warning)
|
||||
:error (= type :error)
|
||||
:success (= type :success)
|
||||
:info (= type :info)
|
||||
:fixed (= position :fixed)
|
||||
:floating (= position :floating)
|
||||
:inline (= position :inline)
|
||||
:hide (= status :hide))}
|
||||
[:div {:class (stl/css :wrapper)}
|
||||
[:div {:class (stl/css :icon)}
|
||||
(case type
|
||||
:warning i/msg-warning-refactor
|
||||
:error i/msg-error-refactor
|
||||
:success i/msg-success-refactor
|
||||
:info i/msg-neutral-refactor
|
||||
i/msg-error-refactor)]
|
||||
[:div {:class (stl/css-case :banner true
|
||||
:warning (= type :warning)
|
||||
:error (= type :error)
|
||||
:success (= type :success)
|
||||
:info (= type :info)
|
||||
:fixed (= position :fixed)
|
||||
:floating (= position :floating)
|
||||
:inline (= position :inline)
|
||||
:hide (= status :hide))}
|
||||
[:div {:class (stl/css :wrapper)}
|
||||
[:div {:class (stl/css :icon)}
|
||||
(case type
|
||||
:warning i/msg-warning-refactor
|
||||
:error i/msg-error-refactor
|
||||
:success i/msg-success-refactor
|
||||
:info i/msg-neutral-refactor
|
||||
i/msg-error-refactor)]
|
||||
|
||||
[:div {:class (stl/css-case :content true
|
||||
:inline-actions (= controls :inline-actions)
|
||||
:bottom-actions (= controls :bottom-actions))
|
||||
:data-test data-test
|
||||
:role role}
|
||||
[:span {:class (stl/css :text)}
|
||||
content
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:* {:key (dm/str "link-" index)}
|
||||
" " [:& lb/link-button {:class "link"
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}]])]
|
||||
[:div {:class (stl/css-case :content true
|
||||
:inline-actions (= controls :inline-actions)
|
||||
:bottom-actions (= controls :bottom-actions))
|
||||
:data-test data-test
|
||||
:role role}
|
||||
[:span {:class (stl/css :text)}
|
||||
content
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:* {:key (dm/str "link-" index)}
|
||||
" " [:& lb/link-button {:class "link"
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}]])]
|
||||
|
||||
(when (or (= controls :bottom-actions) (= controls :inline-actions))
|
||||
[:div {:class (stl/css :actions)}
|
||||
(for [action actions]
|
||||
[:button {:key (uuid/next)
|
||||
:class (stl/css :action-bnt)
|
||||
:on-click (:callback action)}
|
||||
(:label action)])])]
|
||||
(when (= controls :close)
|
||||
[:button {:class (stl/css :btn-close)
|
||||
:on-click on-close} i/close-refactor])]]
|
||||
|
||||
|
||||
|
||||
[:div.banner {:class (dom/classnames
|
||||
:warning (= type :warning)
|
||||
:error (= type :error)
|
||||
:success (= type :success)
|
||||
:info (= type :info)
|
||||
:fixed (= position :fixed)
|
||||
:floating (= position :floating)
|
||||
:inline (= position :inline)
|
||||
:hide (= status :hide))}
|
||||
[:div.wrapper
|
||||
[:div.icon (case type
|
||||
:warning i/msg-warning
|
||||
:error i/msg-error
|
||||
:success i/msg-success
|
||||
:info i/msg-info
|
||||
i/msg-error)]
|
||||
[:div.content {:class (dom/classnames
|
||||
:inline-actions (= controls :inline-actions)
|
||||
:bottom-actions (= controls :bottom-actions))
|
||||
:data-test data-test
|
||||
:role role}
|
||||
[:span
|
||||
content
|
||||
(for [[index link] (d/enumerate links)]
|
||||
[:* {:key (dm/str "link-" index)}
|
||||
" " [:& lb/link-button {:class "link"
|
||||
:on-click (:callback link)
|
||||
:value (:label link)}]])]
|
||||
|
||||
(when (or (= controls :bottom-actions) (= controls :inline-actions))
|
||||
[:div.actions
|
||||
(for [action actions]
|
||||
[:div.btn-secondary.btn-small {:key (uuid/next)
|
||||
:on-click (:callback action)}
|
||||
(:label action)])])]
|
||||
(when (= controls :close)
|
||||
[:div.btn-close {:on-click on-close} i/close])]])))
|
||||
(when (or (= controls :bottom-actions) (= controls :inline-actions))
|
||||
[:div {:class (stl/css :actions)}
|
||||
(for [action actions]
|
||||
[:button {:key (uuid/next)
|
||||
:class (stl/css :action-bnt)
|
||||
:on-click (:callback action)}
|
||||
(:label action)])])]
|
||||
(when (= controls :close)
|
||||
[:button {:class (stl/css :btn-close)
|
||||
:on-click on-close} i/close-refactor])]])
|
||||
|
||||
(mf/defc notifications
|
||||
[]
|
||||
|
||||
@@ -100,15 +100,6 @@
|
||||
@include titleTipography;
|
||||
}
|
||||
|
||||
.inline-actions {
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
}
|
||||
|
||||
.actions {
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
(let [data (unchecked-get props "data")
|
||||
wrapper-ref (mf/use-ref nil)
|
||||
components (mf/deref dm/components)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
allow-click-outside (:allow-click-outside data)
|
||||
|
||||
@@ -78,9 +77,7 @@
|
||||
|
||||
(when-let [component (get components (:type data))]
|
||||
[:div {:ref wrapper-ref
|
||||
:class (stl/css-case
|
||||
:modal-wrapper new-css-system
|
||||
:global/modal-wrapper (not new-css-system))}
|
||||
:class (stl/css :modal-wrapper)}
|
||||
(mf/element component (:props data))])))
|
||||
|
||||
(def modal-ref
|
||||
|
||||
@@ -13,7 +13,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.onboarding.newsletter]
|
||||
[app.main.ui.onboarding.questions]
|
||||
[app.main.ui.onboarding.team-choice]
|
||||
@@ -33,178 +32,113 @@
|
||||
|
||||
(mf/defc onboarding-welcome
|
||||
[{:keys [next] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
go-next
|
||||
(let [go-next
|
||||
(fn []
|
||||
(send-event "onboarding-step1-continue")
|
||||
(next))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/onboarding-welcome.png"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.welcome.title")]]
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/onboarding-welcome.png"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.welcome.title")]]
|
||||
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.welcome.desc1")]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/community.svg"
|
||||
:border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://community.penpot.app/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-community-link")}
|
||||
(tr "onboarding-v2.welcome.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc2")]]]
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.welcome.desc1")]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/community.svg"
|
||||
:border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://community.penpot.app/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-community-link")}
|
||||
(tr "onboarding-v2.welcome.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc2")]]]
|
||||
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/contributing.svg"
|
||||
:border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://help.penpot.app/contributing-guide/"
|
||||
:target "_blank" :on-click #(send-event "onboarding-contributing-link")}
|
||||
(tr "onboarding-v2.welcome.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc3")]]]]]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/contributing.svg"
|
||||
:border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://help.penpot.app/contributing-guide/"
|
||||
:target "_blank" :on-click #(send-event "onboarding-contributing-link")}
|
||||
(tr "onboarding-v2.welcome.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc3")]]]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click go-next
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]]
|
||||
|
||||
|
||||
[:div.modal-container.onboarding.onboarding-v2
|
||||
[:div.modal-left.welcome
|
||||
[:img {:src "images/onboarding-welcome.png" :border "0" :alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div.modal-right
|
||||
[:div.release-container [:span.release "Version " (:main cf/version)]]
|
||||
[:div.right-content
|
||||
[:div.modal-title
|
||||
[:h2 {:data-test "onboarding-welcome"} (tr "onboarding-v2.welcome.title")]]
|
||||
|
||||
[:div.modal-content
|
||||
[:p (tr "onboarding-v2.welcome.desc1")]
|
||||
[:div.welcome-card
|
||||
[:img {:src "images/community.svg" :border "0"}]
|
||||
[:div
|
||||
[:div.title [:a {:href "https://community.penpot.app/" :target "_blank" :on-click #(send-event "onboarding-community-link")} (tr "onboarding-v2.welcome.desc2.title")]]
|
||||
[:div.description (tr "onboarding-v2.welcome.desc2")]]]
|
||||
|
||||
[:div.welcome-card
|
||||
[:img {:src "images/contributing.svg" :border "0"}]
|
||||
[:div
|
||||
[:div.title [:a {:href "https://help.penpot.app/contributing-guide/" :target "_blank" :on-click #(send-event "onboarding-contributing-link")} (tr "onboarding-v2.welcome.desc3.title")]]
|
||||
[:div.description (tr "onboarding-v2.welcome.desc3")]]]]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click go-next :data-test "onboarding-next-btn"} (tr "labels.continue")]]
|
||||
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
|
||||
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
|
||||
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
|
||||
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click go-next
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]]))
|
||||
|
||||
(mf/defc onboarding-before-start
|
||||
[{:keys [next] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
go-next
|
||||
(let [go-next
|
||||
(fn []
|
||||
(send-event "onboarding-step2-continue")
|
||||
(next))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/onboarding-people.png"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.before-start.title")]]
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/onboarding-people.png"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.before-start.title")]]
|
||||
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.before-start.desc1")]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/user-guide.svg" :border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://help.penpot.app/user-guide/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-user-guide-link")}
|
||||
(tr "onboarding-v2.before-start.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc2")]]]
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.before-start.desc1")]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/user-guide.svg" :border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://help.penpot.app/user-guide/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-user-guide-link")}
|
||||
(tr "onboarding-v2.before-start.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc2")]]]
|
||||
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/video-tutorials.svg" :border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://www.youtube.com/c/Penpot"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-video-tutorials-link")}
|
||||
(tr "onboarding-v2.before-start.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc3")]]]]]
|
||||
[:div {:class (stl/css :property-block)}
|
||||
[:img {:src "images/video-tutorials.svg" :border "0"}]
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://www.youtube.com/c/Penpot"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-video-tutorials-link")}
|
||||
(tr "onboarding-v2.before-start.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc3")]]]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click go-next
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]]
|
||||
|
||||
|
||||
[:div.modal-container.onboarding.onboarding-v2
|
||||
[:div.modal-left.welcome
|
||||
[:img {:src "images/onboarding-people.png" :border "0" :alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div.modal-right
|
||||
[:div.release-container [:span.release "Version " (:main cf/version)]]
|
||||
[:div.right-content
|
||||
[:div.modal-title
|
||||
[:h2 {:data-test "onboarding-welcome"} (tr "onboarding-v2.before-start.title")]]
|
||||
|
||||
[:div.modal-content
|
||||
[:p (tr "onboarding-v2.before-start.desc1")]
|
||||
[:div.welcome-card
|
||||
[:img {:src "images/user-guide.svg" :border "0"}]
|
||||
[:div
|
||||
[:div.title [:a {:href "https://help.penpot.app/user-guide/" :target "_blank" :on-click #(send-event "onboarding-user-guide-link")} (tr "onboarding-v2.before-start.desc2.title")]]
|
||||
[:div.description (tr "onboarding-v2.before-start.desc2")]]]
|
||||
|
||||
[:div.welcome-card
|
||||
[:img {:src "images/video-tutorials.svg" :border "0"}]
|
||||
[:div
|
||||
[:div.title [:a {:href "https://www.youtube.com/c/Penpot" :target "_blank" :on-click #(send-event "onboarding-video-tutorials-link")} (tr "onboarding-v2.before-start.desc3.title")]]
|
||||
[:div.description (tr "onboarding-v2.before-start.desc3")]]]]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click go-next :data-test "onboarding-next-btn"} (tr "labels.continue")]]
|
||||
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
|
||||
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
|
||||
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
|
||||
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click go-next
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]]))
|
||||
|
||||
|
||||
(mf/defc onboarding-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding}
|
||||
[_]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
slide (mf/use-state :start)
|
||||
(let [slide (mf/use-state :start)
|
||||
klass (mf/use-state "fadeInDown")
|
||||
|
||||
navigate
|
||||
@@ -230,15 +164,8 @@
|
||||
(reset! klass nil)
|
||||
(tm/dispose! sem))))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated {:class(dm/str @klass " " (stl/css :animated))}
|
||||
(case @slide
|
||||
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
|
||||
:opensource [:& onboarding-before-start {:next skip}])]]
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
(case @slide
|
||||
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
|
||||
:opensource [:& onboarding-before-start {:next skip}])]])))
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated {:class (dm/str @klass " " (stl/css :animated))}
|
||||
(case @slide
|
||||
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
|
||||
:opensource [:& onboarding-before-start {:next skip}])]]))
|
||||
|
||||
@@ -11,7 +11,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.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -20,8 +19,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-newsletter-modal}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
message (tr "onboarding.newsletter.acceptance-message")
|
||||
(let [message (tr "onboarding.newsletter.acceptance-message")
|
||||
newsletter-updates (mf/use-state false)
|
||||
newsletter-news (mf/use-state false)
|
||||
toggle
|
||||
@@ -39,78 +37,49 @@
|
||||
(modal/show {:type :onboarding-team})
|
||||
(du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeInDown {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-newsletter-title"}
|
||||
(tr "onboarding.newsletter.title")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.desc")]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :newsletter-options)}
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-updates"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-updates)}
|
||||
(when @newsletter-updates
|
||||
i/status-tick-refactor)]
|
||||
(tr "onboarding-v2.newsletter.updates")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-updates"
|
||||
:on-change #(toggle newsletter-updates)}]]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeInDown {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-newsletter-title"}
|
||||
(tr "onboarding.newsletter.title")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.desc")]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :newsletter-options)}
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-updates"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-updates)}
|
||||
(when @newsletter-updates
|
||||
i/status-tick-refactor)]
|
||||
(tr "onboarding-v2.newsletter.updates")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-updates"
|
||||
:on-change #(toggle newsletter-updates)}]]]
|
||||
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-news"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-news)}
|
||||
(when @newsletter-news
|
||||
i/status-tick-refactor)]
|
||||
(tr "onboarding-v2.newsletter.news")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-news"
|
||||
:on-change #(toggle newsletter-news)}]]]]
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-news"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-news)}
|
||||
(when @newsletter-news
|
||||
i/status-tick-refactor)]
|
||||
(tr "onboarding-v2.newsletter.news")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-news"
|
||||
:on-change #(toggle newsletter-news)}]]]]
|
||||
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy1")
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:target "_blank"
|
||||
:href "https://penpot.app/privacy"}
|
||||
(tr "onboarding.newsletter.policy")]]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy2")]]]
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy1")
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:target "_blank"
|
||||
:href "https://penpot.app/privacy"}
|
||||
(tr "onboarding.newsletter.policy")]]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy2")]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click accept} (tr "labels.continue")]]
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:button {:on-click accept} (tr "labels.continue")]]
|
||||
|
||||
[:img {:class (stl/css-case :deco true
|
||||
:top true)
|
||||
:src "images/deco-newsletter.png" :border "0"}]]]
|
||||
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.onboarding.newsletter.animated.fadeInDown
|
||||
[:div.modal-top
|
||||
[:h1.newsletter-title {:data-test "onboarding-newsletter-title"} (tr "onboarding.newsletter.title")]
|
||||
[:p (tr "onboarding-v2.newsletter.desc")]]
|
||||
[:div.modal-bottom
|
||||
[:div.newsletter-options
|
||||
[:div.input-checkbox.check-primary
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-updates"
|
||||
:on-change #(toggle newsletter-updates)}]
|
||||
[:label {:for "newsletter-updates"} (tr "onboarding-v2.newsletter.updates")]]
|
||||
[:div.input-checkbox.check-primary
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-news"
|
||||
:on-change #(toggle newsletter-news)}]
|
||||
[:label {:for "newsletter-news"} (tr "onboarding-v2.newsletter.news")]]]
|
||||
[:p (tr "onboarding-v2.newsletter.privacy1") [:a {:target "_blank" :href "https://penpot.app/privacy"} (tr "onboarding.newsletter.policy")]]
|
||||
[:p (tr "onboarding-v2.newsletter.privacy2")]]
|
||||
[:div.modal-footer
|
||||
[:button.btn-primary {:on-click accept} (tr "labels.continue")]]
|
||||
[:img.deco.top {:src "images/deco-newsletter.png" :border "0"}]
|
||||
[:img.deco.newsletter-left {:src "images/deco-news-left.png" :border "0"}]
|
||||
[:img.deco.newsletter-right {:src "images/deco-news-right.png" :border "0"}]]])
|
||||
))
|
||||
[:img {:class (stl/css-case :deco true
|
||||
:top true)
|
||||
:src "images/deco-newsletter.png" :border "0"}]]]))
|
||||
|
||||
@@ -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}])]]))
|
||||
|
||||
@@ -15,7 +15,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.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
@@ -30,64 +29,38 @@
|
||||
|
||||
(mf/defc team-modal-right
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-desc")]
|
||||
[:ul {:class (stl/css :team-features)}
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/document-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-1")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/move-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-2")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/tree-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-3")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/user-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-4")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-5")]]]]
|
||||
|
||||
|
||||
|
||||
[:div.team-right
|
||||
[:h2.subtitle (tr "onboarding.team-modal.create-team")]
|
||||
[:p.info (tr "onboarding.team-modal.create-team-desc")]
|
||||
[:ul.team-features
|
||||
[:li.feature
|
||||
[:span.icon i/file-html]
|
||||
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-1")]]
|
||||
[:li.feature
|
||||
[:span.icon i/pointer-inner]
|
||||
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-2")]]
|
||||
[:li.feature
|
||||
[:span.icon i/tree]
|
||||
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-3")]]
|
||||
[:li.feature
|
||||
[:span.icon i/user]
|
||||
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-4")]]
|
||||
[:li.feature
|
||||
[:span.icon i/tick]
|
||||
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-5")]]]])))
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-desc")]
|
||||
[:ul {:class (stl/css :team-features)}
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/document-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-1")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/move-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-2")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/tree-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-3")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/user-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-4")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.team-modal.create-team-feature-5")]]]])
|
||||
|
||||
(mf/defc onboarding-team-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-team}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
form (fm/use-form :spec ::team-form
|
||||
(let [form (fm/use-form :spec ::team-form
|
||||
:initial {}
|
||||
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
@@ -109,76 +82,43 @@
|
||||
|
||||
teams (mf/deref refs/teams)]
|
||||
|
||||
(if new-css-system
|
||||
(if (< (count teams) 2)
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:div {:class (stl/css :first-block)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form)
|
||||
:on-submit on-submit}
|
||||
(if (< (count teams) 2)
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:div {:class (stl/css :first-block)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form)
|
||||
:on-submit on-submit}
|
||||
|
||||
[:& fm/input {:type "text"
|
||||
:class (stl/css :team-name-input)
|
||||
:name :name
|
||||
:placeholder "Team name"
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:& fm/submit-button*
|
||||
{:className (stl/css :accept-button)
|
||||
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
|
||||
[:div {:class (stl/css :second-block)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :accept-button)
|
||||
:on-click on-skip}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
|
||||
[:& team-modal-right]
|
||||
[:div {:class (stl/css :paginator)} "1/2"]]]
|
||||
|
||||
(st/emit! (modal/hide)))
|
||||
|
||||
|
||||
(if (< (count teams) 2)
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.onboarding-team.animated.fadeIn
|
||||
[:div.team-left
|
||||
[:h2.title (tr "onboarding.team-modal.create-team")]
|
||||
[:p.info (tr "onboarding.choice.team-up.create-team-desc")]
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
[:& fm/input {:type "text"
|
||||
:name :name
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
[:& fm/input {:type "text"
|
||||
:class (stl/css :team-name-input)
|
||||
:name :name
|
||||
:placeholder "Team name"
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:& fm/submit-button*
|
||||
{:label (tr "onboarding.choice.team-up.continue-creating-team")}]]
|
||||
{:className (stl/css :accept-button)
|
||||
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
|
||||
[:div {:class (stl/css :second-block)}
|
||||
[:h2 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
|
||||
[:h2.title (tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p.info (tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :accept-button)
|
||||
:on-click on-skip}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
|
||||
[:& team-modal-right]
|
||||
[:div {:class (stl/css :paginator)} "1/2"]]]
|
||||
|
||||
[:div
|
||||
[:button.btn-primary.btn-large {:on-click on-skip} (tr "onboarding.choice.team-up.continue-without-a-team")]]]
|
||||
[:& team-modal-right]
|
||||
[:div.paginator "1/2"]
|
||||
|
||||
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
|
||||
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
|
||||
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
|
||||
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]]
|
||||
|
||||
(st/emit! (modal/hide))))))
|
||||
(st/emit! (modal/hide)))))
|
||||
|
||||
(defn get-available-roles
|
||||
[]
|
||||
@@ -197,8 +137,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-team-invitations}
|
||||
[{:keys [name] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
initial (mf/use-memo (constantly
|
||||
(let [initial (mf/use-memo (constantly
|
||||
{:role "editor"
|
||||
:name name}))
|
||||
form (fm/use-form :spec ::invite-form
|
||||
@@ -265,96 +204,48 @@
|
||||
(on-invite-now form)
|
||||
(on-invite-later form)))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
|
||||
[:div {:class (stl/css :modal-form)}
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
[:div {:class (stl/css :role-select)}
|
||||
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
[:div {:class (stl/css :modal-form)}
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
[:div {:class (stl/css :role-select)}
|
||||
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
|
||||
[:div {:class (stl/css :invitation-row)}
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]]
|
||||
[:div {:class (stl/css :invitation-row)}
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :back-button)
|
||||
:on-click #(st/emit! (modal/show {:type :onboarding-team})
|
||||
(ptk/event ::ev/event {::ev/name "invite-members-back"
|
||||
::ev/origin "onboarding"
|
||||
:name name
|
||||
:step 2}))}
|
||||
(tr "labels.back")]
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :back-button)
|
||||
:on-click #(st/emit! (modal/show {:type :onboarding-team})
|
||||
(ptk/event ::ev/event {::ev/name "invite-members-back"
|
||||
::ev/origin "onboarding"
|
||||
:name name
|
||||
:step 2}))}
|
||||
(tr "labels.back")]
|
||||
|
||||
[:& fm/submit-button*
|
||||
{:className (stl/css :accept-button)
|
||||
:label
|
||||
(if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))}]]
|
||||
[:div {:class (stl/css :modal-hint)}
|
||||
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
|
||||
[:& fm/submit-button*
|
||||
{:className (stl/css :accept-button)
|
||||
:label
|
||||
(if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))}]]
|
||||
[:div {:class (stl/css :modal-hint)}
|
||||
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
|
||||
|
||||
[:& team-modal-right]
|
||||
[:div {:class (stl/css :paginator)} "2/2"]]]
|
||||
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.onboarding-team-members.animated.fadeIn
|
||||
[:div.team-left
|
||||
[:h2.title (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p.info (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
[:div.invite-row
|
||||
[:div.role-wrapper
|
||||
[:span.rol (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn #{}
|
||||
:on-submit on-submit
|
||||
:label (tr "modals.invite-member.emails")}]]
|
||||
|
||||
[:div.buttons
|
||||
[:button.btn-secondary.btn-large
|
||||
{:on-click #(st/emit! (modal/show {:type :onboarding-team})
|
||||
(ptk/event ::ev/event {::ev/name "invite-members-back"
|
||||
::ev/origin "onboarding"
|
||||
:name name
|
||||
:step 2}))}
|
||||
(tr "labels.back")]
|
||||
[:& fm/submit-button*
|
||||
{:label
|
||||
(if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-send-invites")
|
||||
(tr "onboarding.choice.team-up.create-team-without-inviting"))}]]
|
||||
[:div.skip-action
|
||||
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
|
||||
[:& team-modal-right]
|
||||
[:div.paginator "2/2"]
|
||||
|
||||
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
|
||||
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
|
||||
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
|
||||
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
|
||||
[:& team-modal-right]
|
||||
[:div {:class (stl/css :paginator)} "2/2"]]]))
|
||||
|
||||
|
||||
|
||||
@@ -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])]]]))
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu-a11y :refer [context-menu-a11y]]
|
||||
[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]]
|
||||
@@ -51,8 +50,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :access-token}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
form (fm/use-form
|
||||
(let [form (fm/use-form
|
||||
:initial initial-data
|
||||
:spec ::access-token-form
|
||||
:validators [name-validator
|
||||
@@ -107,176 +105,96 @@
|
||||
:content (tr "dashboard.access-tokens.copied-success")
|
||||
:timeout 1000}))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.create-access-token.title")]
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.create-access-token.title")]
|
||||
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:form form
|
||||
:name :name
|
||||
:disabled @created?
|
||||
:label (tr "modals.create-access-token.name.label")
|
||||
:show-success? true
|
||||
:placeholder (tr "modals.create-access-token.name.placeholder")}]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:form form
|
||||
:name :name
|
||||
:disabled @created?
|
||||
:label (tr "modals.create-access-token.name.label")
|
||||
:show-success? true
|
||||
:placeholder (tr "modals.create-access-token.name.placeholder")}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:div {:class (stl/css :select-title)} (tr "modals.create-access-token.expiration-date.label")]
|
||||
[:& fm/select {:options [{:label (tr "dashboard.access-tokens.expiration-never") :value "never" :key "never"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-30-days") :value "720h" :key "720h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-60-days") :value "1440h" :key "1440h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-90-days") :value "2160h" :key "2160h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-180-days") :value "4320h" :key "4320h"}]
|
||||
:default "never"
|
||||
:disabled @created?
|
||||
:name :expiration-date}]
|
||||
(when @created?
|
||||
[:span.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"))])]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:div {:class (stl/css :select-title)} (tr "modals.create-access-token.expiration-date.label")]
|
||||
[:& fm/select {:options [{:label (tr "dashboard.access-tokens.expiration-never") :value "never" :key "never"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-30-days") :value "720h" :key "720h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-60-days") :value "1440h" :key "1440h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-90-days") :value "2160h" :key "2160h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-180-days") :value "4320h" :key "4320h"}]
|
||||
:default "never"
|
||||
:disabled @created?
|
||||
:name :expiration-date}]
|
||||
(when @created?
|
||||
[: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"))])]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
(when @created?
|
||||
[:div {:class (stl/css :custon-input-wrapper)}
|
||||
[:input {:type "text"
|
||||
:value (:token created "")
|
||||
:class (stl/css :custom-input-token)
|
||||
:placeholder (tr "modals.create-access-token.token")
|
||||
:read-only true}]
|
||||
[:button {:title (tr "modals.create-access-token.copy-token")
|
||||
:class (stl/css :copy-btn)
|
||||
:on-click copy-token}
|
||||
i/clipboard-refactor]])
|
||||
#_(when @created?
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
(when @created?
|
||||
[:div {:class (stl/css :custon-input-wrapper)}
|
||||
[:input {:type "text"
|
||||
:value (:token created "")
|
||||
:class (stl/css :custom-input-token)
|
||||
:placeholder (tr "modals.create-access-token.token")
|
||||
:read-only true}]
|
||||
[:button {:title (tr "modals.create-access-token.copy-token")
|
||||
:class (stl/css :copy-btn)
|
||||
:on-click copy-token}
|
||||
i/clipboard-refactor]])
|
||||
#_(when @created?
|
||||
[:button {:class (stl/css :copy-btn)
|
||||
:title (tr "modals.create-access-token.copy-token")
|
||||
:on-click copy-token}
|
||||
[:span {:class (stl/css :token-value)}(:token created "")]
|
||||
[:span {:class (stl/css :token-value)} (:token created "")]
|
||||
[:span {:class (stl/css :icon)}
|
||||
i/clipboard-refactor]])]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
|
||||
(if @created?
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.close")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:*
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.create-access-token.submit-label")}]])]]]]]
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.access-tokens-modal
|
||||
[:& fm/form {:form form :on-submit on-submit}
|
||||
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (tr "modals.create-access-token.title")]]
|
||||
|
||||
[:div.modal-close-button
|
||||
{:on-click on-close} i/close]]
|
||||
|
||||
[:div.modal-content.generic-form
|
||||
[:div.fields-container
|
||||
[:div.fields-row
|
||||
[:& fm/input {:type "text"
|
||||
:auto-focus? true
|
||||
:form form
|
||||
:name :name
|
||||
:disabled @created?
|
||||
:label (tr "modals.create-access-token.name.label")
|
||||
:placeholder (tr "modals.create-access-token.name.placeholder")}]]
|
||||
|
||||
[:div.fields-row
|
||||
[:& fm/select {:options [{:label (tr "dashboard.access-tokens.expiration-never") :value "never" :key "never"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-30-days") :value "720h" :key "720h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-60-days") :value "1440h" :key "1440h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-90-days") :value "2160h" :key "2160h"}
|
||||
{:label (tr "dashboard.access-tokens.expiration-180-days") :value "4320h" :key "4320h"}]
|
||||
:label (tr "modals.create-access-token.expiration-date.label")
|
||||
:default "never"
|
||||
:disabled @created?
|
||||
:name :expiration-date}]
|
||||
(when @created?
|
||||
[:span.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"))])]
|
||||
|
||||
[:div.fields-row.access-token-created
|
||||
(when @created?
|
||||
[:div.custom-input.with-icon
|
||||
[:input {:type "text"
|
||||
:value (:token created "")
|
||||
:placeholder (tr "modals.create-access-token.token")
|
||||
:read-only true}]
|
||||
[:button.help-icon {:title (tr "modals.create-access-token.copy-token")
|
||||
:on-click copy-token}
|
||||
i/copy]])]]]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
(if @created?
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.close")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:*
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.create-access-token.submit-label")}]])]]]]])))
|
||||
(if @created?
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.close")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:*
|
||||
[:input {:class (stl/css :cancel-button)
|
||||
:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.create-access-token.submit-label")}]])]]]]]))
|
||||
|
||||
(mf/defc access-tokens-hero
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :access-tokens-hero-container)}
|
||||
[:div {:class (stl/css :access-tokens-hero)}
|
||||
[:div {:class (stl/css :desc)}
|
||||
[:h2 (tr "dashboard.access-tokens.personal")]
|
||||
[:p (tr "dashboard.access-tokens.personal.description")]]
|
||||
(let [on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))]
|
||||
[:div {:class (stl/css :access-tokens-hero-container)}
|
||||
[:div {:class (stl/css :access-tokens-hero)}
|
||||
[:div {:class (stl/css :desc)}
|
||||
[:h2 (tr "dashboard.access-tokens.personal")]
|
||||
[:p (tr "dashboard.access-tokens.personal.description")]]
|
||||
|
||||
[:button
|
||||
{:class (stl/css :btn-primary)
|
||||
:on-click on-click}
|
||||
[:span (tr "dashboard.access-tokens.create")]]]]
|
||||
|
||||
;; OLD
|
||||
[:div.access-tokens-hero-container
|
||||
[:div.access-tokens-hero
|
||||
[:div.desc
|
||||
[:h2 (tr "dashboard.access-tokens.personal")]
|
||||
[:p (tr "dashboard.access-tokens.personal.description")]]
|
||||
|
||||
[:button.btn-primary
|
||||
{:on-click on-click}
|
||||
[:span (tr "dashboard.access-tokens.create")]]]])))
|
||||
[:button
|
||||
{:class (stl/css :btn-primary)
|
||||
:on-click on-click}
|
||||
[:span (tr "dashboard.access-tokens.create")]]]]))
|
||||
|
||||
(mf/defc access-token-actions
|
||||
[{:keys [on-delete]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
local (mf/use-state {:menu-open false})
|
||||
(let [local (mf/use-state {:menu-open false})
|
||||
show? (:menu-open @local)
|
||||
options (mf/with-memo [on-delete]
|
||||
[{:option-name (tr "labels.delete")
|
||||
@@ -302,47 +220,25 @@
|
||||
(dom/stop-propagation event)
|
||||
(on-menu-click event))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div
|
||||
{:class (stl/css :icon)
|
||||
:tab-index "0"
|
||||
:ref menu-ref
|
||||
:on-click on-menu-click
|
||||
:on-key-down on-keydown}
|
||||
i/actions
|
||||
[:& context-menu-a11y
|
||||
{:on-close on-menu-close
|
||||
:show show?
|
||||
:fixed? true
|
||||
:min-width? true
|
||||
:top "auto"
|
||||
:left "auto"
|
||||
:options options}]]
|
||||
|
||||
;; OLD
|
||||
[:div.icon
|
||||
{:tab-index "0"
|
||||
:ref menu-ref
|
||||
:on-click on-menu-click
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(dom/stop-propagation event)
|
||||
(on-menu-click event)))}
|
||||
i/actions
|
||||
[:& context-menu-a11y
|
||||
{:on-close on-menu-close
|
||||
:show show?
|
||||
:fixed? true
|
||||
:min-width? true
|
||||
:top "auto"
|
||||
:left "auto"
|
||||
:options options}]])))
|
||||
[:div {:class (stl/css :icon)
|
||||
:tab-index "0"
|
||||
:ref menu-ref
|
||||
:on-click on-menu-click
|
||||
:on-key-down on-keydown}
|
||||
i/actions
|
||||
[:& context-menu-a11y
|
||||
{:on-close on-menu-close
|
||||
:show show?
|
||||
:fixed? true
|
||||
:min-width? true
|
||||
:top "auto"
|
||||
:left "auto"
|
||||
:options options}]]))
|
||||
|
||||
(mf/defc access-token-item
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [token] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
locale (mf/deref i18n/locale)
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
expires-at (:expires-at token)
|
||||
expires-txt (some-> expires-at (dt/format-date-locale {:locale locale}))
|
||||
expired? (and (some? expires-at) (> (dt/now) expires-at))
|
||||
@@ -366,66 +262,36 @@
|
||||
:accept-label (tr "modals.delete-acces-token.accept")
|
||||
:on-accept delete-fn}))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :table-row)}
|
||||
[:div {:class (stl/css :table-field :name)}
|
||||
(str (:name token))]
|
||||
[:div {:class (stl/css :table-row)}
|
||||
[:div {:class (stl/css :table-field :name)}
|
||||
(str (:name token))]
|
||||
|
||||
[:div {:class (stl/css :table-field :expiration-date)}
|
||||
[:span {:class (stl/css-case :expired expired? :content true)}
|
||||
(cond
|
||||
(nil? expires-at) (tr "dashboard.access-tokens.no-expiration")
|
||||
expired? (tr "dashboard.access-tokens.expired-on" expires-txt)
|
||||
:else (tr "dashboard.access-tokens.expires-on" expires-txt))]]
|
||||
[:div {:class (stl/css :table-field :actions)}
|
||||
[:& access-token-actions
|
||||
{:on-delete on-delete}]]]
|
||||
|
||||
;; OLD
|
||||
[:div.table-row
|
||||
[:div.table-field.name
|
||||
(str (:name token))]
|
||||
[:div.table-field.expiration-date
|
||||
[:span.content {:class (when expired? "expired")}
|
||||
(cond
|
||||
(nil? expires-at) (tr "dashboard.access-tokens.no-expiration")
|
||||
expired? (tr "dashboard.access-tokens.expired-on" expires-txt)
|
||||
:else (tr "dashboard.access-tokens.expires-on" expires-txt))]]
|
||||
[:div.table-field.actions
|
||||
[:& access-token-actions
|
||||
{:on-delete on-delete}]]])))
|
||||
[:div {:class (stl/css :table-field :expiration-date)}
|
||||
[:span {:class (stl/css-case :expired expired? :content true)}
|
||||
(cond
|
||||
(nil? expires-at) (tr "dashboard.access-tokens.no-expiration")
|
||||
expired? (tr "dashboard.access-tokens.expired-on" expires-txt)
|
||||
:else (tr "dashboard.access-tokens.expires-on" expires-txt))]]
|
||||
[:div {:class (stl/css :table-field :actions)}
|
||||
[:& access-token-actions
|
||||
{:on-delete on-delete}]]]))
|
||||
|
||||
(mf/defc access-tokens-page
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
tokens (mf/deref tokens-ref)]
|
||||
(let [tokens (mf/deref tokens-ref)]
|
||||
(mf/with-effect []
|
||||
(dom/set-html-title (tr "title.settings.access-tokens"))
|
||||
(st/emit! (du/fetch-access-tokens)))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :dashboard-access-tokens)}
|
||||
[:div
|
||||
[:& access-tokens-hero]
|
||||
(if (empty? tokens)
|
||||
[:div {:class (stl/css :access-tokens-empty)}
|
||||
[:div (tr "dashboard.access-tokens.empty.no-access-tokens")]
|
||||
[:div (tr "dashboard.access-tokens.empty.add-one")]]
|
||||
[:div {:class (stl/css :dashboard-table)}
|
||||
[:div {:class (stl/css :table-rows)}
|
||||
(for [token tokens]
|
||||
[:& access-token-item {:token token :key (:id token)}])]])]]
|
||||
|
||||
;; OLD
|
||||
[:div.dashboard-access-tokens
|
||||
[:div
|
||||
[:& access-tokens-hero]
|
||||
(if (empty? tokens)
|
||||
[:div.access-tokens-empty
|
||||
[:div (tr "dashboard.access-tokens.empty.no-access-tokens")]
|
||||
[:div (tr "dashboard.access-tokens.empty.add-one")]]
|
||||
[:div.dashboard-table
|
||||
[:div.table-rows
|
||||
(for [token tokens]
|
||||
[:& access-token-item {:token token :key (:id token)}])]])]])))
|
||||
[:div {:class (stl/css :dashboard-access-tokens)}
|
||||
[:div
|
||||
[:& access-tokens-hero]
|
||||
(if (empty? tokens)
|
||||
[:div {:class (stl/css :access-tokens-empty)}
|
||||
[:div (tr "dashboard.access-tokens.empty.no-access-tokens")]
|
||||
[:div (tr "dashboard.access-tokens.empty.add-one")]]
|
||||
[:div {:class (stl/css :dashboard-table)}
|
||||
[:div {:class (stl/css :table-rows)}
|
||||
(for [token tokens]
|
||||
[:& access-token-item {:token token :key (:id token)}])]])]]))
|
||||
|
||||
|
||||
@@ -12,88 +12,6 @@
|
||||
font-size: $fs-16;
|
||||
margin-top: $s-20;
|
||||
width: $s-800;
|
||||
|
||||
.table-header {
|
||||
color: $df-secondary;
|
||||
display: grid;
|
||||
font-size: $fs-12;
|
||||
grid-template-columns: 43% 1fr $s-108 $s-12;
|
||||
height: $s-40;
|
||||
max-width: $s-1000;
|
||||
padding: 0 $s-16;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-rows {
|
||||
color: $db-secondary;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: $s-16;
|
||||
max-width: $s-1000;
|
||||
padding-top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
align-items: center;
|
||||
background-color: $db-tertiary;
|
||||
border-radius: $br-8;
|
||||
color: $df-primary;
|
||||
display: grid;
|
||||
font-size: $fs-14;
|
||||
grid-template-columns: 1fr 43% $s-12;
|
||||
height: fit-content;
|
||||
min-height: $s-40;
|
||||
padding: 0 $s-16;
|
||||
width: 100%;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: $s-8;
|
||||
}
|
||||
}
|
||||
|
||||
.table-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
padding-left: $s-12;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.name {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
color: $df-primary;
|
||||
display: -webkit-box;
|
||||
max-width: $s-480;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.expiration-date {
|
||||
color: $df-secondary;
|
||||
font-size: $fs-14;
|
||||
|
||||
.content {
|
||||
padding: $s-2 $s-6;
|
||||
&.expired {
|
||||
background-color: var(--warning-color);
|
||||
border-radius: $br-4;
|
||||
color: $db-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.access-token-created {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
&.actions {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
width: $s-12;
|
||||
height: $s-12;
|
||||
@@ -101,6 +19,87 @@
|
||||
}
|
||||
}
|
||||
|
||||
.table-header {
|
||||
color: $df-secondary;
|
||||
display: grid;
|
||||
font-size: $fs-12;
|
||||
grid-template-columns: 43% 1fr $s-108 $s-12;
|
||||
height: $s-40;
|
||||
max-width: $s-1000;
|
||||
padding: 0 $s-16;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-rows {
|
||||
color: $db-secondary;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: $s-16;
|
||||
max-width: $s-1000;
|
||||
padding-top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
align-items: center;
|
||||
background-color: $db-tertiary;
|
||||
border-radius: $br-8;
|
||||
color: $df-primary;
|
||||
display: grid;
|
||||
font-size: $fs-14;
|
||||
grid-template-columns: 1fr 43% $s-12;
|
||||
height: fit-content;
|
||||
min-height: $s-40;
|
||||
padding: 0 $s-16;
|
||||
width: 100%;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: $s-8;
|
||||
}
|
||||
}
|
||||
|
||||
.table-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
padding-left: $s-12;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.name {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
color: $df-primary;
|
||||
display: -webkit-box;
|
||||
max-width: $s-480;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.expiration-date {
|
||||
color: $df-secondary;
|
||||
font-size: $fs-14;
|
||||
|
||||
.content {
|
||||
padding: $s-2 $s-6;
|
||||
&.expired {
|
||||
background-color: var(--warning-color);
|
||||
border-radius: $br-4;
|
||||
color: $db-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.access-token-created {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
&.actions {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-access-tokens {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -171,75 +170,85 @@
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,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.main.ui.icons :as i]
|
||||
[app.main.ui.messages :as msgs]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
@@ -76,8 +75,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :change-email}
|
||||
[]
|
||||
(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 ::email-change-form
|
||||
:validators [email-equality]
|
||||
:initial profile)
|
||||
@@ -99,82 +97,44 @@
|
||||
(when (and different-emails-error? (= email-1 email-2))
|
||||
(swap! form d/dissoc-in [:errors :email-2])))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "change-email-title"}
|
||||
(tr "modals.change-email.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "change-email-title"}
|
||||
(tr "modals.change-email.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& msgs/inline-banner
|
||||
{:type :info
|
||||
:content (tr "modals.change-email.info" (:email profile))}]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& msgs/inline-banner
|
||||
{:type :info
|
||||
:content (tr "modals.change-email.info" (:email profile))}]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-1
|
||||
:label (tr "modals.change-email.new-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-1
|
||||
:label (tr "modals.change-email.new-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-2
|
||||
:label (tr "modals.change-email.confirm-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]]
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-2
|
||||
:label (tr "modals.change-email.confirm-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)
|
||||
:data-test "change-email-submit"}
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.change-email.submit")}]]]]]]
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.change-email-modal.form-container
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-submit}
|
||||
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 {:data-test "change-email-title"}
|
||||
(tr "modals.change-email.title")]]
|
||||
[:div.modal-close-button
|
||||
{:on-click on-close} i/close]]
|
||||
|
||||
[:div.modal-content
|
||||
[:& msgs/inline-banner
|
||||
{:type :info
|
||||
:content (tr "modals.change-email.info" (:email profile))}]
|
||||
|
||||
[:div.fields-container
|
||||
[:div.fields-row
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-1
|
||||
:label (tr "modals.change-email.new-email")
|
||||
:trim true
|
||||
:on-change-value on-email-change}]]
|
||||
[:div.fields-row
|
||||
[:& fm/input {:type "email"
|
||||
:name :email-2
|
||||
:label (tr "modals.change-email.confirm-email")
|
||||
:trim true
|
||||
:on-change-value on-email-change}]]]]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons {:data-test "change-email-submit"}
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.change-email.submit")}]]]]]])
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)
|
||||
:data-test "change-email-submit"}
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.change-email.submit")}]]]]]]
|
||||
))
|
||||
|
||||
|
||||
|
||||
@@ -8,46 +8,50 @@
|
||||
|
||||
.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;
|
||||
@include titleTipography;
|
||||
gap: $s-24;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
@include titleTipography;
|
||||
gap: $s-24;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.fields-row {
|
||||
@include flexColumn;
|
||||
}
|
||||
|
||||
.select-title {
|
||||
@include titleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
button {
|
||||
@extend .modal-accept-btn;
|
||||
}
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,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.icons :as i]
|
||||
[app.main.ui.messages :as msgs]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
@@ -29,8 +28,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :delete-account}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
on-close
|
||||
(let [on-close
|
||||
(mf/use-callback #(st/emit! (modal/hide)))
|
||||
|
||||
on-accept
|
||||
@@ -39,52 +37,28 @@
|
||||
(du/request-account-deletion
|
||||
(with-meta {} {:on-error on-error}))))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.delete-account.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.delete-account.title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content (tr "modals.delete-account.info")}]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content (tr "modals.delete-account.info")}]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :cancel-button)
|
||||
:on-click on-close}
|
||||
(tr "modals.delete-account.cancel")]
|
||||
[:button {:class (stl/css-case :accept-button true
|
||||
:danger true)
|
||||
:on-click on-accept
|
||||
:data-test "delete-account-btn"}
|
||||
(tr "modals.delete-account.confirm")]]]]]
|
||||
|
||||
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.change-email-modal
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (tr "modals.delete-account.title")]]
|
||||
[:div.modal-close-button
|
||||
{:on-click on-close} i/close]]
|
||||
|
||||
[:div.modal-content
|
||||
[:& msgs/inline-banner
|
||||
{:type :warning
|
||||
:content (tr "modals.delete-account.info")}]]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:button.btn-danger.btn-large {:on-click on-accept
|
||||
:data-test "delete-account-btn"}
|
||||
(tr "modals.delete-account.confirm")]
|
||||
[:button.btn-secondary.btn-large {:on-click on-close}
|
||||
(tr "modals.delete-account.cancel")]]]]])))
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :cancel-button)
|
||||
:on-click on-close}
|
||||
(tr "modals.delete-account.cancel")]
|
||||
[:button {:class (stl/css-case :accept-button true
|
||||
:danger true)
|
||||
:on-click on-accept
|
||||
:data-test "delete-account-btn"}
|
||||
(tr "modals.delete-account.confirm")]]]]]))
|
||||
|
||||
|
||||
@@ -8,50 +8,54 @@
|
||||
|
||||
.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;
|
||||
@include titleTipography;
|
||||
gap: $s-24;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-header {
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
.modal-title {
|
||||
@include tabTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
.accept-button {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-close-btn {
|
||||
@extend .modal-close-btn-base;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include flexColumn;
|
||||
@include titleTipography;
|
||||
gap: $s-24;
|
||||
margin-bottom: $s-24;
|
||||
}
|
||||
|
||||
.fields-row {
|
||||
@include flexColumn;
|
||||
}
|
||||
|
||||
.select-title {
|
||||
@include titleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend .modal-action-btns;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.accept-button {
|
||||
@extend .modal-accept-btn;
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]]])
|
||||
|
||||
@@ -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 {}]]])
|
||||
|
||||
|
||||
@@ -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}]]])
|
||||
|
||||
@@ -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]]])
|
||||
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
|
||||
@@ -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}]
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.viewer.inspect.annotation :refer [annotation]]
|
||||
[app.main.ui.viewer.inspect.attributes.blur :refer [blur-panel]]
|
||||
@@ -36,65 +35,35 @@
|
||||
|
||||
(mf/defc attributes
|
||||
[{:keys [page-id file-id shapes frame from libraries share-id objects]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
shapes (hooks/use-equal-memo shapes)
|
||||
(let [shapes (hooks/use-equal-memo shapes)
|
||||
type (if (= (count shapes) 1) (-> shapes first :type) :multiple)
|
||||
options (type->options type)
|
||||
content (when (= (count shapes) 1)
|
||||
(ctkl/get-component-annotation (first shapes) libraries))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :element-options)}
|
||||
(for [[idx option] (map-indexed vector options)]
|
||||
[:> (case option
|
||||
:geometry geometry-panel
|
||||
:layout layout-panel
|
||||
:layout-element layout-element-panel
|
||||
:fill fill-panel
|
||||
:stroke stroke-panel
|
||||
:shadow shadow-panel
|
||||
:blur blur-panel
|
||||
:image image-panel
|
||||
:text text-panel
|
||||
:svg svg-panel)
|
||||
{:key idx
|
||||
:shapes shapes
|
||||
:objects objects
|
||||
:frame frame
|
||||
:from from}])
|
||||
(when content
|
||||
[:& annotation {:content content}])
|
||||
[:& exports
|
||||
{:shapes shapes
|
||||
:type type
|
||||
:page-id page-id
|
||||
:file-id file-id
|
||||
:share-id share-id}]]
|
||||
|
||||
|
||||
[:div.element-options
|
||||
(for [[idx option] (map-indexed vector options)]
|
||||
[:> (case option
|
||||
:geometry geometry-panel
|
||||
:layout layout-panel
|
||||
:layout-element layout-element-panel
|
||||
:fill fill-panel
|
||||
:stroke stroke-panel
|
||||
:shadow shadow-panel
|
||||
:blur blur-panel
|
||||
:image image-panel
|
||||
:text text-panel
|
||||
:svg svg-panel)
|
||||
{:key idx
|
||||
:shapes shapes
|
||||
:objects objects
|
||||
:frame frame
|
||||
:from from}])
|
||||
(when content
|
||||
[:& annotation {:content content}])
|
||||
[:& exports
|
||||
{:shapes shapes
|
||||
:type type
|
||||
:page-id page-id
|
||||
:file-id file-id
|
||||
:share-id share-id}]])))
|
||||
[:div {:class (stl/css :element-options)}
|
||||
(for [[idx option] (map-indexed vector options)]
|
||||
[:> (case option
|
||||
:geometry geometry-panel
|
||||
:layout layout-panel
|
||||
:layout-element layout-element-panel
|
||||
:fill fill-panel
|
||||
:stroke stroke-panel
|
||||
:shadow shadow-panel
|
||||
:blur blur-panel
|
||||
:image image-panel
|
||||
:text text-panel
|
||||
:svg svg-panel)
|
||||
{:key idx
|
||||
:shapes shapes
|
||||
:objects objects
|
||||
:frame frame
|
||||
:from from}])
|
||||
(when content
|
||||
[:& annotation {:content content}])
|
||||
[:& exports
|
||||
{:shapes shapes
|
||||
:type type
|
||||
:page-id page-id
|
||||
:file-id file-id
|
||||
:share-id share-id}]]))
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
[app.main.ui.components.code-block :refer [code-block]]
|
||||
[app.main.ui.components.copy-button :refer [copy-button]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||
[app.main.ui.icons :as i]
|
||||
@@ -100,8 +99,7 @@
|
||||
|
||||
(mf/defc code
|
||||
[{:keys [shapes frame on-expand from]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
style-type* (mf/use-state "css")
|
||||
(let [style-type* (mf/use-state "css")
|
||||
markup-type* (mf/use-state "html")
|
||||
fontfaces-css* (mf/use-state nil)
|
||||
images-data* (mf/use-state nil)
|
||||
@@ -232,135 +230,80 @@
|
||||
(fn [result]
|
||||
(reset! images-data* result)))))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :element-options)}
|
||||
[:div {:class (stl/css :attributes-block)}
|
||||
[:button {:class (stl/css :download-button)
|
||||
:on-click handle-copy-all-code}
|
||||
"Copy all code"]]
|
||||
[:div {:class (stl/css :element-options)}
|
||||
[:div {:class (stl/css :attributes-block)}
|
||||
[:button {:class (stl/css :download-button)
|
||||
:on-click handle-copy-all-code}
|
||||
"Copy all code"]]
|
||||
|
||||
#_[:div.attributes-block
|
||||
[:button.download-button {:on-click handle-open-review}
|
||||
"Preview"]]
|
||||
#_[:div.attributes-block
|
||||
[:button.download-button {:on-click handle-open-review}
|
||||
"Preview"]]
|
||||
|
||||
[:div {:class (stl/css :code-block)}
|
||||
[:div {:class (stl/css :code-row-lang)}
|
||||
[:button {:class (stl/css :toggle-btn)
|
||||
:data-type "css"
|
||||
:on-click handle-collapse}
|
||||
[:span {:class (stl/css-case
|
||||
:collapsabled-icon true
|
||||
:rotated collapsed-css?)}
|
||||
i/arrow-refactor]]
|
||||
[:div {:class (stl/css :code-block)}
|
||||
[:div {:class (stl/css :code-row-lang)}
|
||||
[:button {:class (stl/css :toggle-btn)
|
||||
:data-type "css"
|
||||
:on-click handle-collapse}
|
||||
[:span {:class (stl/css-case
|
||||
:collapsabled-icon true
|
||||
:rotated collapsed-css?)}
|
||||
i/arrow-refactor]]
|
||||
|
||||
[:& select {:default-value style-type
|
||||
:class (stl/css :code-lang-select)
|
||||
:options [{:label "CSS" :value "css"}]}]
|
||||
[:& select {:default-value style-type
|
||||
:class (stl/css :code-lang-select)
|
||||
:on-change set-style
|
||||
:options [{:label "CSS" :value "css"}]}]
|
||||
|
||||
[:div {:class (stl/css :action-btns)}
|
||||
[:button {:class (stl/css :expand-button)
|
||||
:on-click on-expand}
|
||||
i/code-refactor]
|
||||
[:div {:class (stl/css :action-btns)}
|
||||
[:button {:class (stl/css :expand-button)
|
||||
:on-click on-expand}
|
||||
i/code-refactor]
|
||||
|
||||
[:& copy-button {:data #(replace-map style-code images-data)
|
||||
:on-copied on-style-copied}]]]
|
||||
[:& copy-button {:data #(replace-map style-code images-data)
|
||||
:on-copied on-style-copied}]]]
|
||||
|
||||
(when-not collapsed-css?
|
||||
[:div {:class (stl/css :code-row-display)
|
||||
:style #js {"--code-height" (str (or style-size 400) "px")}}
|
||||
[:& code-block {:type style-type
|
||||
:code style-code}]])
|
||||
|
||||
[:div {:class (stl/css :resize-area)
|
||||
:on-pointer-down on-style-pointer-down
|
||||
:on-lost-pointer-capture on-style-lost-pointer-capture
|
||||
:on-pointer-move on-style-pointer-move}]]
|
||||
|
||||
[:div {:class (stl/css :code-block)}
|
||||
[:div {:class (stl/css :code-row-lang)}
|
||||
[:button {:class (stl/css :toggle-btn)
|
||||
:data-type "markup"
|
||||
:on-click handle-collapse}
|
||||
[:span {:class (stl/css-case
|
||||
:collapsabled-icon true
|
||||
:rotated collapsed-markup?)}
|
||||
i/arrow-refactor]]
|
||||
[:& select {:default-value markup-type
|
||||
:class (stl/css :code-lang-select)
|
||||
:options [{:label "HTML" :value "html"}
|
||||
{:label "SVG" :value "svg"}]
|
||||
:on-change set-markup}]
|
||||
|
||||
[:div {:class (stl/css :action-btns)}
|
||||
[:button {:class (stl/css :expand-button)
|
||||
:on-click on-expand}
|
||||
i/code-refactor]
|
||||
|
||||
[:& copy-button {:data #(replace-map markup-code images-data)
|
||||
:on-copied on-markup-copied}]]]
|
||||
|
||||
(when-not collapsed-markup?
|
||||
[:div {:class (stl/css :code-row-display)
|
||||
:style #js {"--code-height" (str (or markup-size 400) "px")}}
|
||||
[:& code-block {:type markup-type
|
||||
:code markup-code}]])
|
||||
|
||||
[:div {:class (stl/css :resize-area)
|
||||
:on-pointer-down on-markup-pointer-down
|
||||
:on-lost-pointer-capture on-markup-lost-pointer-capture
|
||||
:on-pointer-move on-markup-pointer-move}]]]
|
||||
|
||||
|
||||
|
||||
[:div.element-options
|
||||
[:div.attributes-block
|
||||
[:button.download-button {:on-click handle-copy-all-code}
|
||||
"Copy all code"]]
|
||||
|
||||
#_[:div.attributes-block
|
||||
[:button.download-button {:on-click handle-open-review}
|
||||
"Preview"]]
|
||||
|
||||
[:div.code-block
|
||||
[:div.code-row-lang
|
||||
[:& select {:default-value style-type
|
||||
:class "custom-select"
|
||||
:options [{:label "CSS" :value "css"}]
|
||||
:on-change set-style}]
|
||||
[:button.expand-button
|
||||
{:on-click on-expand}
|
||||
i/full-screen]
|
||||
|
||||
[:& copy-button {:data #(replace-map style-code images-data)
|
||||
:on-copied on-style-copied}]]
|
||||
|
||||
[:div.code-row-display {:style #js {"--code-height" (str (or style-size 400) "px")}}
|
||||
(when-not collapsed-css?
|
||||
[:div {:class (stl/css :code-row-display)
|
||||
:style #js {"--code-height" (str (or style-size 400) "px")}}
|
||||
[:& code-block {:type style-type
|
||||
:code style-code}]]
|
||||
:code style-code}]])
|
||||
|
||||
[:div.resize-area {:on-pointer-down on-style-pointer-down
|
||||
:on-lost-pointer-capture on-style-lost-pointer-capture
|
||||
:on-pointer-move on-style-pointer-move}]]
|
||||
[:div {:class (stl/css :resize-area)
|
||||
:on-pointer-down on-style-pointer-down
|
||||
:on-lost-pointer-capture on-style-lost-pointer-capture
|
||||
:on-pointer-move on-style-pointer-move}]]
|
||||
|
||||
[:div.code-block
|
||||
[:div.code-row-lang
|
||||
[:& select {:default-value markup-type
|
||||
:class "input-option"
|
||||
:options [{:label "HTML" :value "html"}
|
||||
{:label "SVG" :value "svg"}]
|
||||
:on-change set-markup}]
|
||||
[:div {:class (stl/css :code-block)}
|
||||
[:div {:class (stl/css :code-row-lang)}
|
||||
[:button {:class (stl/css :toggle-btn)
|
||||
:data-type "markup"
|
||||
:on-click handle-collapse}
|
||||
[:span {:class (stl/css-case
|
||||
:collapsabled-icon true
|
||||
:rotated collapsed-markup?)}
|
||||
i/arrow-refactor]]
|
||||
[:& select {:default-value markup-type
|
||||
:class (stl/css :code-lang-select)
|
||||
:options [{:label "HTML" :value "html"}
|
||||
{:label "SVG" :value "svg"}]
|
||||
:on-change set-markup}]
|
||||
|
||||
[:button.expand-button
|
||||
{:on-click on-expand}
|
||||
i/full-screen]
|
||||
[:div {:class (stl/css :action-btns)}
|
||||
[:button {:class (stl/css :expand-button)
|
||||
:on-click on-expand}
|
||||
i/code-refactor]
|
||||
|
||||
[:& copy-button {:data #(replace-map markup-code images-data)
|
||||
:on-copied on-markup-copied}]]
|
||||
[:& copy-button {:data #(replace-map markup-code images-data)
|
||||
:on-copied on-markup-copied}]]]
|
||||
|
||||
[:div.code-row-display {:style #js {"--code-height" (str (or markup-size 400) "px")}}
|
||||
(when-not collapsed-markup?
|
||||
[:div {:class (stl/css :code-row-display)
|
||||
:style #js {"--code-height" (str (or markup-size 400) "px")}}
|
||||
[:& code-block {:type markup-type
|
||||
:code markup-code}]]
|
||||
:code markup-code}]])
|
||||
|
||||
[:div.resize-area {:on-pointer-down on-markup-pointer-down
|
||||
:on-lost-pointer-capture on-markup-lost-pointer-capture
|
||||
:on-pointer-move on-markup-pointer-move}]]])))
|
||||
[:div {:class (stl/css :resize-area)
|
||||
:on-pointer-down on-markup-pointer-down
|
||||
:on-lost-pointer-capture on-markup-lost-pointer-capture
|
||||
:on-pointer-move on-markup-pointer-move}]]]))
|
||||
|
||||
@@ -12,80 +12,85 @@
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding-bottom: $s-16;
|
||||
}
|
||||
|
||||
.attributes-block {
|
||||
.download-button {
|
||||
@extend .button-secondary;
|
||||
@include tabTitleTipography;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
margin: $s-8 0;
|
||||
}
|
||||
}
|
||||
.code-block {
|
||||
@include codeTypography;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
.download-button {
|
||||
@extend .button-secondary;
|
||||
@include tabTitleTipography;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
margin: $s-8 0;
|
||||
}
|
||||
|
||||
.code-block {
|
||||
@include codeTypography;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding: 0 $s-4 $s-8 0;
|
||||
|
||||
pre {
|
||||
border-radius: $br-8;
|
||||
padding: $s-16;
|
||||
max-height: var(--code-height);
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding: 0 $s-4 $s-8 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
border-radius: $br-8;
|
||||
padding: $s-16;
|
||||
max-height: var(--code-height);
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
// Overrides background setted in the theme
|
||||
:global(.hljs) {
|
||||
background: $db-tertiary;
|
||||
}
|
||||
}
|
||||
|
||||
// Overrides background setted in the theme
|
||||
:global(.hljs) {
|
||||
background: $db-tertiary;
|
||||
}
|
||||
}
|
||||
.code-row-lang {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: $s-4;
|
||||
width: 100%;
|
||||
}
|
||||
.code-lang {
|
||||
@include tabTitleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.action-btns {
|
||||
display: flex;
|
||||
gap: $s-4;
|
||||
flex: 1;
|
||||
justify-content: end;
|
||||
.expand-button {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
.code-lang-select {
|
||||
@include tabTitleTipography;
|
||||
width: $s-72;
|
||||
border: $s-1 solid transparent;
|
||||
background-color: transparent;
|
||||
color: var(--menu-foreground-color-disabled);
|
||||
}
|
||||
.code-row-display {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding-bottom: $s-8;
|
||||
.code-row-lang {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: $s-4;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.code-lang {
|
||||
@include tabTitleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-btns {
|
||||
display: flex;
|
||||
gap: $s-4;
|
||||
flex: 1;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.expand-button {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.code-lang-select {
|
||||
@include tabTitleTipography;
|
||||
width: $s-72;
|
||||
border: $s-1 solid transparent;
|
||||
background-color: transparent;
|
||||
color: var(--menu-foreground-color-disabled);
|
||||
}
|
||||
|
||||
.code-row-display {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding-bottom: $s-8;
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
@include buttonStyle;
|
||||
display: flex;
|
||||
|
||||
@@ -10,11 +10,8 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.shape-icon :as si]
|
||||
[app.main.ui.components.shape-icon-refactor :as sir]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.viewer.inspect.attributes :refer [attributes]]
|
||||
[app.main.ui.viewer.inspect.code :refer [code]]
|
||||
@@ -44,8 +41,7 @@
|
||||
(mf/defc right-sidebar
|
||||
[{:keys [frame page objects file selected shapes page-id file-id share-id from on-change-section on-expand]
|
||||
:or {from :inspect}}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
section (mf/use-state :info #_:code)
|
||||
(let [section (mf/use-state :info #_:code)
|
||||
objects (or objects (:objects page))
|
||||
shapes (or shapes
|
||||
(resolve-shapes objects selected))
|
||||
@@ -86,113 +82,60 @@
|
||||
(when-not (seq shapes)
|
||||
(handle-change-tab :info))))
|
||||
|
||||
(if new-css-system
|
||||
[:aside {:class (stl/css-case :settings-bar-right true
|
||||
:viewer-code (= from :inspect))}
|
||||
(if (seq shapes)
|
||||
[:div {:class (stl/css :tool-windows)}
|
||||
[:div {:class (stl/css :shape-row)}
|
||||
(if (> (count shapes) 1)
|
||||
[:*
|
||||
[:span {:class (stl/css :layers-icon)} i/layers-refactor]
|
||||
[:span {:class (stl/css :layer-title)} (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
|
||||
[:*
|
||||
[:span {:class (stl/css :shape-icon)}
|
||||
[:& sir/element-icon-refactor {:shape first-shape :main-instance? main-instance?}]]
|
||||
;; Execution time translation strings:
|
||||
;; inspect.tabs.code.selected.circle
|
||||
;; inspect.tabs.code.selected.component
|
||||
;; inspect.tabs.code.selected.curve
|
||||
;; inspect.tabs.code.selected.frame
|
||||
;; inspect.tabs.code.selected.group
|
||||
;; inspect.tabs.code.selected.image
|
||||
;; inspect.tabs.code.selected.mask
|
||||
;; inspect.tabs.code.selected.path
|
||||
;; inspect.tabs.code.selected.rect
|
||||
;; inspect.tabs.code.selected.svg-raw
|
||||
;; inspect.tabs.code.selected.text
|
||||
[:span {:class (stl/css :layer-title)} (:name first-shape)]])]
|
||||
[:div {:class (stl/css :inspect-content)}
|
||||
[:& tab-container {:on-change-tab handle-change-tab
|
||||
:selected @section}
|
||||
[:& tab-element {:id :info :title (tr "inspect.tabs.info")}
|
||||
[:& attributes {:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]]
|
||||
[:aside {:class (stl/css-case :settings-bar-right true
|
||||
:viewer-code (= from :inspect))}
|
||||
(if (seq shapes)
|
||||
[:div {:class (stl/css :tool-windows)}
|
||||
[:div {:class (stl/css :shape-row)}
|
||||
(if (> (count shapes) 1)
|
||||
[:*
|
||||
[:span {:class (stl/css :layers-icon)} i/layers-refactor]
|
||||
[:span {:class (stl/css :layer-title)} (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
|
||||
[:*
|
||||
[:span {:class (stl/css :shape-icon)}
|
||||
[:& sir/element-icon-refactor {:shape first-shape :main-instance? main-instance?}]]
|
||||
;; Execution time translation strings:
|
||||
;; inspect.tabs.code.selected.circle
|
||||
;; inspect.tabs.code.selected.component
|
||||
;; inspect.tabs.code.selected.curve
|
||||
;; inspect.tabs.code.selected.frame
|
||||
;; inspect.tabs.code.selected.group
|
||||
;; inspect.tabs.code.selected.image
|
||||
;; inspect.tabs.code.selected.mask
|
||||
;; inspect.tabs.code.selected.path
|
||||
;; inspect.tabs.code.selected.rect
|
||||
;; inspect.tabs.code.selected.svg-raw
|
||||
;; inspect.tabs.code.selected.text
|
||||
[:span {:class (stl/css :layer-title)} (:name first-shape)]])]
|
||||
[:div {:class (stl/css :inspect-content)}
|
||||
[:& tab-container {:on-change-tab handle-change-tab
|
||||
:selected @section}
|
||||
[:& tab-element {:id :info :title (tr "inspect.tabs.info")}
|
||||
[:& attributes {:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]]
|
||||
|
||||
[:& tab-element {:id :code :title (tr "inspect.tabs.code")}
|
||||
[:& code {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}]]]]]
|
||||
[:div {:class (stl/css :empty)}
|
||||
[:div {:class (stl/css :code-info)}
|
||||
[:span {:class (stl/css :placeholder-icon)}
|
||||
i/code-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "inspect.empty.select")]]
|
||||
[:div {:class (stl/css :help-info)}
|
||||
[:span {:class (stl/css :placeholder-icon)}
|
||||
i/help-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "inspect.empty.help")]]
|
||||
[:button {:class (stl/css :more-info-btn)
|
||||
:on-click navigate-to-help}
|
||||
(tr "inspect.empty.more-info")]])]
|
||||
|
||||
|
||||
[:aside.settings-bar.settings-bar-right
|
||||
[:div.settings-bar-inside
|
||||
(if (seq shapes)
|
||||
[:div.tool-window
|
||||
[:div.tool-window-bar.big
|
||||
(if (> (count shapes) 1)
|
||||
[:*
|
||||
[:span.tool-window-bar-icon i/layers]
|
||||
[:span.tool-window-bar-title (tr "inspect.tabs.code.selected.multiple" (count shapes))]]
|
||||
[:*
|
||||
[:span.tool-window-bar-icon
|
||||
[:& si/element-icon {:shape first-shape :main-instance? main-instance?}]]
|
||||
;; Execution time translation strings:
|
||||
;; inspect.tabs.code.selected.circle
|
||||
;; inspect.tabs.code.selected.component
|
||||
;; inspect.tabs.code.selected.curve
|
||||
;; inspect.tabs.code.selected.frame
|
||||
;; inspect.tabs.code.selected.group
|
||||
;; inspect.tabs.code.selected.image
|
||||
;; inspect.tabs.code.selected.mask
|
||||
;; inspect.tabs.code.selected.path
|
||||
;; inspect.tabs.code.selected.rect
|
||||
;; inspect.tabs.code.selected.svg-raw
|
||||
;; inspect.tabs.code.selected.text
|
||||
[:span.tool-window-bar-title (:name first-shape)]])]
|
||||
[:div.tool-window-content.inspect
|
||||
[:& tabs-container {:on-change-tab handle-change-tab
|
||||
:selected @section}
|
||||
[:& tabs-element {:id :info :title (tr "inspect.tabs.info")}
|
||||
[:& attributes {:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]]
|
||||
|
||||
[:& tabs-element {:id :code :title (tr "inspect.tabs.code")}
|
||||
[:& code {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}]]]]]
|
||||
[:div.empty
|
||||
[:span.tool-window-bar-icon i/code]
|
||||
[:div (tr "inspect.empty.select")]
|
||||
[:span.tool-window-bar-icon i/help]
|
||||
[:div (tr "inspect.empty.help")]
|
||||
[:button.btn-primary.action {:on-click navigate-to-help} (tr "inspect.empty.more-info")]])]])
|
||||
))
|
||||
[:& tab-element {:id :code :title (tr "inspect.tabs.code")}
|
||||
[:& code {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}]]]]]
|
||||
[:div {:class (stl/css :empty)}
|
||||
[:div {:class (stl/css :code-info)}
|
||||
[:span {:class (stl/css :placeholder-icon)}
|
||||
i/code-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "inspect.empty.select")]]
|
||||
[:div {:class (stl/css :help-info)}
|
||||
[:span {:class (stl/css :placeholder-icon)}
|
||||
i/help-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "inspect.empty.help")]]
|
||||
[:button {:class (stl/css :more-info-btn)
|
||||
:on-click navigate-to-help}
|
||||
(tr "inspect.empty.more-info")]])]))
|
||||
|
||||
@@ -16,63 +16,73 @@
|
||||
grid-area: right-sidebar;
|
||||
padding-top: $s-8;
|
||||
padding-left: $s-12;
|
||||
.tool-windows {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.shape-row {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
align-items: center;
|
||||
margin-bottom: $s-16;
|
||||
.layers-icon,
|
||||
.shape-icon {
|
||||
@include flexCenter;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
.layer-title {
|
||||
@include titleTipography;
|
||||
color: $df-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: $s-40;
|
||||
padding-top: $s-24;
|
||||
.code-info,
|
||||
.help-info {
|
||||
@include flexColumn;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: $s-8;
|
||||
.placeholder-icon {
|
||||
@extend .empty-icon;
|
||||
}
|
||||
.placeholder-label {
|
||||
@include titleTipography;
|
||||
text-align: center;
|
||||
width: $s-200;
|
||||
color: $df-secondary;
|
||||
}
|
||||
}
|
||||
.more-info-btn {
|
||||
@extend .button-secondary;
|
||||
@include tabTitleTipography;
|
||||
height: $s-32;
|
||||
padding: $s-8 $s-24;
|
||||
}
|
||||
}
|
||||
.inspect-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
&.viewer-code {
|
||||
height: calc(100vh - $s-48);
|
||||
}
|
||||
}
|
||||
|
||||
.tool-windows {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.shape-row {
|
||||
display: flex;
|
||||
gap: $s-8;
|
||||
align-items: center;
|
||||
margin-bottom: $s-16;
|
||||
}
|
||||
|
||||
.layers-icon,
|
||||
.shape-icon {
|
||||
@include flexCenter;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-title {
|
||||
@include titleTipography;
|
||||
color: $df-primary;
|
||||
}
|
||||
|
||||
.empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: $s-40;
|
||||
padding-top: $s-24;
|
||||
}
|
||||
|
||||
.code-info,
|
||||
.help-info {
|
||||
@include flexColumn;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
@extend .empty-icon;
|
||||
}
|
||||
|
||||
.placeholder-label {
|
||||
@include titleTipography;
|
||||
text-align: center;
|
||||
width: $s-200;
|
||||
color: var(--empty-message-foreground-color);
|
||||
}
|
||||
|
||||
.more-info-btn {
|
||||
@extend .button-secondary;
|
||||
@include tabTitleTipography;
|
||||
height: $s-32;
|
||||
padding: $s-8 $s-24;
|
||||
}
|
||||
|
||||
.inspect-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
[app.main.ui.auth.login :refer [login-methods]]
|
||||
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
|
||||
[app.main.ui.auth.register :refer [register-methods register-validate-form register-success-page]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
@@ -27,8 +26,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :login-register}
|
||||
[_]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
uri (. (. js/document -location) -href)
|
||||
(let [uri (. (. js/document -location) -href)
|
||||
user-email (mf/use-state "")
|
||||
register-token (mf/use-state "")
|
||||
|
||||
@@ -71,114 +69,58 @@
|
||||
(mf/with-effect []
|
||||
(swap! storage assoc :redirect-url uri))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:title (tr "labels.close")
|
||||
:on-click close} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:title (tr "labels.close")
|
||||
:on-click close} i/close-refactor]]
|
||||
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
|
||||
(case current-section
|
||||
:login
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& login-methods {:on-success-callback success-login :origin :viewer}]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:a {:on-click set-section
|
||||
:data-value :recovery-request}
|
||||
(tr "auth.forgot-password")]]
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:span (tr "auth.register") " "]
|
||||
[:a {:on-click set-section
|
||||
:data-value :register}
|
||||
(tr "auth.register-submit")]]]]
|
||||
(case current-section
|
||||
:login
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& login-methods {:on-success-callback success-login :origin :viewer}]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:a {:on-click set-section
|
||||
:data-value :recovery-request}
|
||||
(tr "auth.forgot-password")]]
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:span (tr "auth.register") " "]
|
||||
[:a {:on-click set-section
|
||||
:data-value :register}
|
||||
(tr "auth.register-submit")]]]]
|
||||
|
||||
:register
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-methods {:on-success-callback success-register}]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
[:a {:on-click set-section
|
||||
:data-value :login}
|
||||
(tr "auth.login-here")]]]]
|
||||
:register
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-methods {:on-success-callback success-register}]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
[:a {:on-click set-section
|
||||
:data-value :login}
|
||||
(tr "auth.login-here")]]]]
|
||||
|
||||
:register-validate
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-validate-form {:params {:token @register-token}
|
||||
:on-success-callback success-email-sent}]
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:a {:on-click set-section
|
||||
:data-value :register}
|
||||
(tr "labels.go-back")]]]]
|
||||
|
||||
:recovery-request
|
||||
[:& recovery-request-page {:go-back-callback go-back-to-login
|
||||
:register-validate
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-validate-form {:params {:token @register-token}
|
||||
:on-success-callback success-email-sent}]
|
||||
:email-sent
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-success-page {:params {:email @user-email}}]])
|
||||
[:div {:class (stl/css :links)}
|
||||
[:div {:class (stl/css :link-entry)}
|
||||
[:a {:on-click set-section
|
||||
:data-value :register}
|
||||
(tr "labels.go-back")]]]]
|
||||
|
||||
(when main-section
|
||||
[:div {:class (stl/css :links)}
|
||||
[:& terms-login]])]]]
|
||||
:recovery-request
|
||||
[:& recovery-request-page {:go-back-callback go-back-to-login
|
||||
:on-success-callback success-email-sent}]
|
||||
:email-sent
|
||||
[:div {:class (stl/css :form-container)}
|
||||
[:& register-success-page {:params {:email @user-email}}]])
|
||||
|
||||
|
||||
;;OLD
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.login-register
|
||||
[:div.title
|
||||
[:div.modal-close-button {:on-click close :title (tr "labels.close")}
|
||||
i/close]
|
||||
(when main-section
|
||||
[:h2 (tr "labels.continue-with-penpot")])]
|
||||
|
||||
[:div.modal-bottom.auth-content
|
||||
|
||||
(case current-section
|
||||
:login
|
||||
[:div.generic-form.login-form
|
||||
[:div.form-container
|
||||
[:& login-methods {:on-success-callback success-login}]
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:a {:on-click #(set-current-section :recovery-request)}
|
||||
(tr "auth.forgot-password")]]
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.register") " "]
|
||||
[:a {:on-click #(set-current-section :register)}
|
||||
(tr "auth.register-submit")]]]]]
|
||||
|
||||
:register
|
||||
[:div.form-container
|
||||
[:& register-methods {:on-success-callback success-register}]
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:span (tr "auth.already-have-account") " "]
|
||||
[:a {:on-click #(set-current-section :login)}
|
||||
(tr "auth.login-here")]]]]
|
||||
|
||||
:register-validate
|
||||
[:div.form-container
|
||||
[:& register-validate-form {:params {:token @register-token}
|
||||
:on-success-callback success-email-sent}]
|
||||
[:div.links
|
||||
[:div.link-entry
|
||||
[:a {:on-click #(set-current-section :register)}
|
||||
(tr "labels.go-back")]]]]
|
||||
|
||||
:recovery-request
|
||||
[:& recovery-request-page {:go-back-callback #(set-current-section :login)
|
||||
:on-success-callback success-email-sent}]
|
||||
:email-sent
|
||||
[:div.form-container
|
||||
[:& register-success-page {:params {:email @user-email}}]])]
|
||||
|
||||
(when main-section
|
||||
[:div.modal-footer.links
|
||||
[:& terms-login]])]])))
|
||||
(when main-section
|
||||
[:div {:class (stl/css :links)}
|
||||
[:& terms-login]])]]]))
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[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,8 +39,7 @@
|
||||
::mf/register-as :share-link
|
||||
::mf/wrap-props false}
|
||||
[{:keys [file page]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
current-page page
|
||||
(let [current-page page
|
||||
current-page-id (:id page)
|
||||
slinks (mf/deref refs/share-links)
|
||||
router (mf/deref refs/router)
|
||||
@@ -165,274 +163,151 @@
|
||||
(reset! confirm* false)
|
||||
(swap! options* assoc :who-comment value))]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :share-modal)}
|
||||
[:div {:class (stl/css :share-link-dialog)}
|
||||
[:div {:class (stl/css :share-link-header)}
|
||||
[:h2 {:class (stl/css :share-link-title)}
|
||||
(tr "common.share-link.title")]
|
||||
[:button {:class (stl/css :modal-close-button)
|
||||
:on-click on-close
|
||||
:title (tr "labels.close")}
|
||||
i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :share-link-section)}
|
||||
(when (and (not confirm?) (some? current-link))
|
||||
[:div {:class (stl/css :custon-input-wrapper)}
|
||||
[:input {:class (stl/css :input-text)
|
||||
:type "text"
|
||||
:value (or current-link "")
|
||||
:placeholder (tr "common.share-link.placeholder")
|
||||
:read-only true}]
|
||||
|
||||
[:button {:class (stl/css :copy-button)
|
||||
:title (tr "viewer.header.share.copy-link")
|
||||
:on-click copy-link}
|
||||
i/clipboard-refactor]])
|
||||
|
||||
[:div {:class (stl/css :hint-wrapper)}
|
||||
(when (not ^boolean confirm?)
|
||||
[:div {:class (stl/css :hint)} (tr "common.share-link.permissions-hint")])
|
||||
(cond
|
||||
(true? confirm?)
|
||||
[:div {:class (stl/css :confirm-dialog)}
|
||||
[:div {:class (stl/css :description)}
|
||||
(tr "common.share-link.confirm-deletion-link-description")]
|
||||
[:div {:class (stl/css :actions)}
|
||||
[:input {:type "button"
|
||||
:class (stl/css :button-cancel)
|
||||
:on-click #(reset! confirm* false)
|
||||
:value (tr "labels.cancel")}]
|
||||
[:input {:type "button"
|
||||
:class (stl/css :button-danger)
|
||||
:on-click delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]]]
|
||||
|
||||
(some? current-link)
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css :button-danger)
|
||||
:on-click try-delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]
|
||||
|
||||
:else
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css :button-active)
|
||||
:on-click create-link
|
||||
:value (tr "common.share-link.get-link")}])]]
|
||||
[:div {:class (stl/css :share-modal)}
|
||||
[:div {:class (stl/css :share-link-dialog)}
|
||||
[:div {:class (stl/css :share-link-header)}
|
||||
[:h2 {:class (stl/css :share-link-title)}
|
||||
(tr "common.share-link.title")]
|
||||
[:button {:class (stl/css :modal-close-button)
|
||||
:on-click on-close
|
||||
:title (tr "labels.close")}
|
||||
i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :share-link-section)}
|
||||
(when (and (not confirm?) (some? current-link))
|
||||
[:div {:class (stl/css :custon-input-wrapper)}
|
||||
[:input {:class (stl/css :input-text)
|
||||
:type "text"
|
||||
:value (or current-link "")
|
||||
:placeholder (tr "common.share-link.placeholder")
|
||||
:read-only true}]
|
||||
|
||||
[:button {:class (stl/css :copy-button)
|
||||
:title (tr "viewer.header.share.copy-link")
|
||||
:on-click copy-link}
|
||||
i/clipboard-refactor]])
|
||||
|
||||
[:div {:class (stl/css :hint-wrapper)}
|
||||
(when (not ^boolean confirm?)
|
||||
[:div {:class (stl/css :permissions-section)}
|
||||
[:button {:class (stl/css :manage-permissions)
|
||||
:on-click toggle-perms-visibility}
|
||||
[:span {:class (stl/css-case :icon true
|
||||
:rotated perms-visible?)}
|
||||
i/arrow-refactor]
|
||||
(tr "common.share-link.manage-ops")]
|
||||
[:div {:class (stl/css :hint)} (tr "common.share-link.permissions-hint")])
|
||||
(cond
|
||||
(true? confirm?)
|
||||
[:div {:class (stl/css :confirm-dialog)}
|
||||
[:div {:class (stl/css :description)}
|
||||
(tr "common.share-link.confirm-deletion-link-description")]
|
||||
[:div {:class (stl/css :actions)}
|
||||
[:input {:type "button"
|
||||
:class (stl/css :button-cancel)
|
||||
:on-click #(reset! confirm* false)
|
||||
:value (tr "labels.cancel")}]
|
||||
[:input {:type "button"
|
||||
:class (stl/css :button-danger)
|
||||
:on-click delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]]]
|
||||
|
||||
(when ^boolean perms-visible?
|
||||
[:*
|
||||
(let [all-selected? (:all-pages options)
|
||||
pages (->> (get-in file [:data :pages])
|
||||
(map #(get-in file [:data :pages-index %])))
|
||||
selected (:pages options)]
|
||||
[:div {:class (stl/css :view-mode)}
|
||||
[:div {:class (stl/css :subtitle)}
|
||||
(tr "common.share-link.permissions-pages")]
|
||||
[:div {:class (stl/css :items)}
|
||||
(if (= 1 (count pages))
|
||||
(some? current-link)
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css :button-danger)
|
||||
:on-click try-delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]
|
||||
|
||||
[:div {:class (stl/css :checkbox-wrapper)}
|
||||
[:input {:type "checkbox"
|
||||
:id (dm/str "page-" current-page-id)
|
||||
:data-page-id (dm/str current-page-id)
|
||||
:on-change on-mark-checked-page
|
||||
:checked true}]
|
||||
[:label {:for (str "page-" current-page-id)} (:name current-page)]
|
||||
[:span {:class (stl/css-case :checkobox-tick true
|
||||
:global/checked true)}
|
||||
i/status-tick-refactor]
|
||||
[:span (str " " (tr "common.share-link.current-tag"))]]
|
||||
:else
|
||||
[:input
|
||||
{:type "button"
|
||||
:class (stl/css :button-active)
|
||||
:on-click create-link
|
||||
:value (tr "common.share-link.get-link")}])]]
|
||||
|
||||
[:*
|
||||
[:div {:class (stl/css :select-all-row)}
|
||||
[:div {:class (stl/css :checkbox-wrapper)}
|
||||
[:label {:for "view-all"
|
||||
:class (stl/css :select-all-label)}
|
||||
[:span {:class (stl/css-case :global/checked all-selected?)}
|
||||
(when all-selected?
|
||||
i/status-tick-refactor)]
|
||||
(tr "common.share-link.view-all")
|
||||
[:input {:type "checkbox"
|
||||
:id "view-all"
|
||||
:checked all-selected?
|
||||
:name "pages-mode"
|
||||
:on-change on-toggle-all}]]]
|
||||
|
||||
[:span {:class (stl/css :count-pages)}
|
||||
(tr "common.share-link.page-shared" (i18n/c (count selected)))]]
|
||||
(when (not ^boolean confirm?)
|
||||
[:div {:class (stl/css :permissions-section)}
|
||||
[:button {:class (stl/css :manage-permissions)
|
||||
:on-click toggle-perms-visibility}
|
||||
[:span {:class (stl/css-case :icon true
|
||||
:rotated perms-visible?)}
|
||||
i/arrow-refactor]
|
||||
(tr "common.share-link.manage-ops")]
|
||||
|
||||
[:ul {:class (stl/css :pages-selection)}
|
||||
(for [{:keys [id name]} pages]
|
||||
[:li {:class (stl/css :checkbox-wrapper)
|
||||
:key (dm/str id)}
|
||||
[:label {:for (dm/str "page-" id)}
|
||||
[:span {:class (stl/css-case :global/checked (contains? selected id))}
|
||||
(when (contains? selected id)
|
||||
i/status-tick-refactor)]
|
||||
name
|
||||
(when (= current-page-id id)
|
||||
[:div {:class (stl/css :current-tag)} (dm/str " " (tr "common.share-link.current-tag"))])
|
||||
[:input {:type "checkbox"
|
||||
:id (dm/str "page-" id)
|
||||
:data-page-id (dm/str id)
|
||||
:on-change on-mark-checked-page
|
||||
:checked (contains? selected id)}]]])]])]])
|
||||
|
||||
[:div {:class (stl/css :access-mode)}
|
||||
(when ^boolean perms-visible?
|
||||
[:*
|
||||
(let [all-selected? (:all-pages options)
|
||||
pages (->> (get-in file [:data :pages])
|
||||
(map #(get-in file [:data :pages-index %])))
|
||||
selected (:pages options)]
|
||||
[:div {:class (stl/css :view-mode)}
|
||||
[:div {:class (stl/css :subtitle)}
|
||||
(tr "common.share-link.permissions-can-comment")]
|
||||
[:div {:class (stl/css :items)}
|
||||
[:& select
|
||||
{:class (stl/css :who-comment-select)
|
||||
:default-value (dm/str (:who-comment options))
|
||||
:options [{:value "team" :label (tr "common.share-link.team-members")}
|
||||
{:value "all" :label (tr "common.share-link.all-users")}]
|
||||
:on-change on-comment-change}]]]
|
||||
[:div {:class (stl/css :inspect-mode)}
|
||||
[:div {:class (stl/css :subtitle)}
|
||||
(tr "common.share-link.permissions-can-inspect")]
|
||||
[:div {:class (stl/css :items)}
|
||||
[:& select
|
||||
{:class (stl/css :who-inspect-select)
|
||||
:default-value (dm/str (:who-inspect options))
|
||||
:options [{:value "team" :label (tr "common.share-link.team-members")}
|
||||
{:value "all" :label (tr "common.share-link.all-users")}]
|
||||
:on-change on-inspect-change}]]]])])]]]
|
||||
|
||||
|
||||
;;OLD
|
||||
[:div.modal-overlay.transparent.share-modal
|
||||
[:div.modal-container.share-link-dialog
|
||||
[:div.modal-content.initial
|
||||
[:div.title
|
||||
[:h2 (tr "common.share-link.title")]
|
||||
[:div.modal-close-button
|
||||
{:on-click on-close
|
||||
:title (tr "labels.close")}
|
||||
i/close]]]
|
||||
[:div.modal-content
|
||||
[:div.share-link-section
|
||||
(when (and (not confirm?) (some? current-link))
|
||||
[:div.custom-input.with-icon
|
||||
[:input {:type "text"
|
||||
:value (or current-link "")
|
||||
:placeholder (tr "common.share-link.placeholder")
|
||||
:read-only true}]
|
||||
[:div.help-icon {:title (tr "viewer.header.share.copy-link")
|
||||
:on-click copy-link}
|
||||
i/copy]])
|
||||
[:div.hint-wrapper
|
||||
(when (not ^boolean confirm?)
|
||||
[:div.hint (tr "common.share-link.permissions-hint")])
|
||||
(cond
|
||||
(true? confirm?)
|
||||
[:div.confirm-dialog
|
||||
[:div.description (tr "common.share-link.confirm-deletion-link-description")]
|
||||
[:div.actions
|
||||
[:input.btn-secondary
|
||||
{:type "button"
|
||||
:on-click #(reset! confirm* false)
|
||||
:value (tr "labels.cancel")}]
|
||||
[:input.btn-danger
|
||||
{:type "button"
|
||||
:on-click delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]]]
|
||||
|
||||
(some? current-link)
|
||||
[:input.btn-secondary
|
||||
{:type "button"
|
||||
:class "primary"
|
||||
:on-click try-delete-link
|
||||
:value (tr "common.share-link.destroy-link")}]
|
||||
|
||||
:else
|
||||
[:input.btn-primary
|
||||
{:type "button"
|
||||
:class "primary"
|
||||
:on-click create-link
|
||||
:value (tr "common.share-link.get-link")}])]]]
|
||||
[:div.modal-content.ops-section
|
||||
[:div.manage-permissions
|
||||
{:on-click toggle-perms-visibility}
|
||||
[:span.icon i/picker-hsv]
|
||||
[:div.title (tr "common.share-link.manage-ops")]]
|
||||
(when ^boolean perms-visible?
|
||||
[:*
|
||||
(let [all-selected? (:all-pages options)
|
||||
pages (->> (get-in file [:data :pages])
|
||||
(map #(get-in file [:data :pages-index %])))
|
||||
selected (:pages options)]
|
||||
[:*
|
||||
[:div.view-mode
|
||||
[:div.subtitle
|
||||
[:span.icon i/play]
|
||||
(tr "common.share-link.permissions-pages")]
|
||||
[:div.items
|
||||
[:div {:class (stl/css :items)}
|
||||
(if (= 1 (count pages))
|
||||
[:div.input-checkbox.check-primary
|
||||
|
||||
[:div {:class (stl/css :checkbox-wrapper)}
|
||||
[:input {:type "checkbox"
|
||||
:id (dm/str "page-" current-page-id)
|
||||
:data-page-id (dm/str current-page-id)
|
||||
:on-change on-mark-checked-page
|
||||
:checked true}]
|
||||
[:label {:for (str "page-" current-page-id)} (:name current-page)]
|
||||
[:span {:class (stl/css-case :checkobox-tick true
|
||||
:global/checked true)}
|
||||
i/status-tick-refactor]
|
||||
[:span (str " " (tr "common.share-link.current-tag"))]]
|
||||
|
||||
[:*
|
||||
[:div.row
|
||||
[:div.input-checkbox.check-primary
|
||||
[:input {:type "checkbox"
|
||||
:id "view-all"
|
||||
:checked all-selected?
|
||||
:name "pages-mode"
|
||||
:on-change on-toggle-all}]
|
||||
[:label {:for "view-all"} (tr "common.share-link.view-all")]]
|
||||
[:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
|
||||
[:div {:class (stl/css :select-all-row)}
|
||||
[:div {:class (stl/css :checkbox-wrapper)}
|
||||
[:label {:for "view-all"
|
||||
:class (stl/css :select-all-label)}
|
||||
[:span {:class (stl/css-case :global/checked all-selected?)}
|
||||
(when all-selected?
|
||||
i/status-tick-refactor)]
|
||||
(tr "common.share-link.view-all")
|
||||
[:input {:type "checkbox"
|
||||
:id "view-all"
|
||||
:checked all-selected?
|
||||
:name "pages-mode"
|
||||
:on-change on-toggle-all}]]]
|
||||
|
||||
[:ul.pages-selection
|
||||
[:span {:class (stl/css :count-pages)}
|
||||
(tr "common.share-link.page-shared" (i18n/c (count selected)))]]
|
||||
|
||||
[:ul {:class (stl/css :pages-selection)}
|
||||
(for [{:keys [id name]} pages]
|
||||
[:li.input-checkbox.check-primary {:key (dm/str id)}
|
||||
[:input {:type "checkbox"
|
||||
:id (dm/str "page-" id)
|
||||
:data-page-id (dm/str id)
|
||||
:on-change on-mark-checked-page
|
||||
:checked (contains? selected id)}]
|
||||
(if (= current-page-id id)
|
||||
[:*
|
||||
[:label {:for (dm/str "page-" id)} name]
|
||||
[:span.current-tag (dm/str " " (tr "common.share-link.current-tag"))]]
|
||||
[:label {:for (dm/str "page-" id)} name])])]])]]])
|
||||
[:div.access-mode
|
||||
[:div.subtitle
|
||||
[:span.icon i/chat]
|
||||
(tr "common.share-link.permissions-can-comment")]
|
||||
[:div.items
|
||||
[:select.input-select {:on-change on-comment-change
|
||||
:value (:who-comment options)}
|
||||
[:option {:value "team"} (tr "common.share-link.team-members")]
|
||||
[:option {:value "all"} (tr "common.share-link.all-users")]]]]
|
||||
[:div.inspect-mode
|
||||
[:div.subtitle
|
||||
[:span.icon i/code]
|
||||
(tr "common.share-link.permissions-can-inspect")]
|
||||
[:div.items
|
||||
[:select.input-select {:on-change on-inspect-change
|
||||
:value (:who-inspect options)}
|
||||
[:option {:value "team"} (tr "common.share-link.team-members")]
|
||||
[:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]])))
|
||||
[:li {:class (stl/css :checkbox-wrapper)
|
||||
:key (dm/str id)}
|
||||
[:label {:for (dm/str "page-" id)}
|
||||
[:span {:class (stl/css-case :global/checked (contains? selected id))}
|
||||
(when (contains? selected id)
|
||||
i/status-tick-refactor)]
|
||||
name
|
||||
(when (= current-page-id id)
|
||||
[:div {:class (stl/css :current-tag)} (dm/str " " (tr "common.share-link.current-tag"))])
|
||||
[:input {:type "checkbox"
|
||||
:id (dm/str "page-" id)
|
||||
:data-page-id (dm/str id)
|
||||
:on-change on-mark-checked-page
|
||||
:checked (contains? selected id)}]]])]])]])
|
||||
|
||||
[:div {:class (stl/css :access-mode)}
|
||||
[:div {:class (stl/css :subtitle)}
|
||||
(tr "common.share-link.permissions-can-comment")]
|
||||
[:div {:class (stl/css :items)}
|
||||
[:& select
|
||||
{:class (stl/css :who-comment-select)
|
||||
:default-value (dm/str (:who-comment options))
|
||||
:options [{:value "team" :label (tr "common.share-link.team-members")}
|
||||
{:value "all" :label (tr "common.share-link.all-users")}]
|
||||
:on-change on-comment-change}]]]
|
||||
[:div {:class (stl/css :inspect-mode)}
|
||||
[:div {:class (stl/css :subtitle)}
|
||||
(tr "common.share-link.permissions-can-inspect")]
|
||||
[:div {:class (stl/css :items)}
|
||||
[:& select
|
||||
{:class (stl/css :who-inspect-select)
|
||||
:default-value (dm/str (:who-inspect options))
|
||||
:options [{:value "team" :label (tr "common.share-link.team-members")}
|
||||
{:value "all" :label (tr "common.share-link.all-users")}]
|
||||
:on-change on-inspect-change}]]]])])]]]))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -90,12 +90,12 @@
|
||||
{:key (dm/str "workspace-" page-id)
|
||||
:ref node-ref}
|
||||
|
||||
[:section.workspace-viewport
|
||||
[:section {:class (stl/css :workspace-viewport)}
|
||||
(when (dbg/enabled? :coordinates)
|
||||
[:& coordinates/coordinates {:colorpalette? colorpalette?}])
|
||||
|
||||
(when (dbg/enabled? :history-overlay)
|
||||
[:div.history-debug-overlay
|
||||
[:div {:class (stl/css :history-debug-overlay)}
|
||||
[:button {:on-click #(st/emit! dw/reinitialize-undo)} "CLEAR"]
|
||||
[:& history-toolbox]])
|
||||
|
||||
|
||||
@@ -40,3 +40,25 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-content {
|
||||
grid-area: viewport;
|
||||
}
|
||||
|
||||
.history-debug-overlay {
|
||||
bottom: 0;
|
||||
max-height: $s-500;
|
||||
width: $s-500;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
z-index: $z-index-modal;
|
||||
}
|
||||
|
||||
.workspace-viewport {
|
||||
overflow: hidden;
|
||||
transition: none;
|
||||
display: grid;
|
||||
grid-template-rows: $s-20 1fr;
|
||||
grid-template-columns: $s-20 1fr;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -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}]])]]))
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
(mf/defc sidebar-options
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
{cmode :mode cshow :show} (mf/deref refs/comments-local)
|
||||
(let [{cmode :mode cshow :show} (mf/deref refs/comments-local)
|
||||
update-mode
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
@@ -45,53 +44,30 @@
|
||||
(let [mode (if (= :pending cshow) :all :pending)]
|
||||
(st/emit! (dcm/update-filters {:show mode})))))]
|
||||
|
||||
(if new-css-system
|
||||
[:ul {:class (stl/css :comment-mode-dropdown)}
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (or (= :all cmode) (nil? cmode)))
|
||||
:data-value "all"
|
||||
:on-click update-mode}
|
||||
[:ul {:class (stl/css :comment-mode-dropdown)}
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (or (= :all cmode) (nil? cmode)))
|
||||
:data-value "all"
|
||||
:on-click update-mode}
|
||||
|
||||
[:span {:class (stl/css :label)} (tr "labels.show-all-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (= :yours cmode))
|
||||
:data-value "yours"
|
||||
:on-click update-mode}
|
||||
[:span {:class (stl/css :label)} (tr "labels.show-your-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||
[:li {:class (stl/css :separator)}]
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (= :pending cshow))
|
||||
:on-click update-show}
|
||||
[:span {:class (stl/css :label)} (tr "labels.hide-resolved-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]]
|
||||
|
||||
|
||||
[:ul.dropdown.with-check
|
||||
[:li {:class (dom/classnames :selected (or (= :all cmode) (nil? cmode)))
|
||||
:data-value "all"
|
||||
:on-click update-mode}
|
||||
[:span.icon i/tick]
|
||||
[:span.label (tr "labels.show-all-comments")]]
|
||||
|
||||
[:li {:class (dom/classnames :selected (= :yours cmode))
|
||||
:data-value "yours"
|
||||
:on-click update-mode}
|
||||
[:span.icon i/tick]
|
||||
[:span.label (tr "labels.show-your-comments")]]
|
||||
|
||||
[:hr]
|
||||
|
||||
[:li {:class (dom/classnames :selected (= :pending cshow))
|
||||
:on-click update-show}
|
||||
[:span.icon i/tick]
|
||||
[:span.label (tr "labels.hide-resolved-comments")]]])))
|
||||
[:span {:class (stl/css :label)} (tr "labels.show-all-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (= :yours cmode))
|
||||
:data-value "yours"
|
||||
:on-click update-mode}
|
||||
[:span {:class (stl/css :label)} (tr "labels.show-your-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]
|
||||
[:li {:class (stl/css :separator)}]
|
||||
[:li {:class (stl/css-case :dropdown-item true
|
||||
:selected (= :pending cshow))
|
||||
:on-click update-show}
|
||||
[:span {:class (stl/css :label)} (tr "labels.hide-resolved-comments")]
|
||||
[:span {:class (stl/css :icon)} i/tick-refactor]]]))
|
||||
|
||||
(mf/defc comments-sidebar
|
||||
[{:keys [users threads page-id from-viewer]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
threads-map (mf/deref refs/threads-ref)
|
||||
(let [threads-map (mf/deref refs/threads-ref)
|
||||
profile (mf/deref refs/profile)
|
||||
users-refs (mf/deref refs/current-file-comments-users)
|
||||
users (or users users-refs)
|
||||
@@ -139,75 +115,41 @@
|
||||
(dwcm/center-to-comment-thread thread)
|
||||
(-> (dcm/open-thread thread)
|
||||
(with-meta {::ev/origin "workspace"})))))))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :comments-section)}
|
||||
[:div {:class (stl/css :comments-section-title)}
|
||||
[:span (tr "labels.comments")]
|
||||
[:button {:class (stl/css :close-button)
|
||||
:on-click close-section}
|
||||
i/close-refactor]]
|
||||
[:div {:class (stl/css :comments-section)}
|
||||
[:div {:class (stl/css :comments-section-title)}
|
||||
[:span (tr "labels.comments")]
|
||||
[:button {:class (stl/css :close-button)
|
||||
:on-click close-section}
|
||||
i/close-refactor]]
|
||||
|
||||
[:button {:class (stl/css :mode-dropdown-wrapper)
|
||||
:on-click toggle-mode-selector}
|
||||
[:button {:class (stl/css :mode-dropdown-wrapper)
|
||||
:on-click toggle-mode-selector}
|
||||
|
||||
[:span {:class (stl/css :mode-label)} (case (:mode local)
|
||||
(nil :all) (tr "labels.show-all-comments")
|
||||
:yours (tr "labels.show-your-comments"))]
|
||||
[:div {:class (stl/css :icon)} i/arrow-refactor]]
|
||||
[:span {:class (stl/css :mode-label)} (case (:mode local)
|
||||
(nil :all) (tr "labels.show-all-comments")
|
||||
:yours (tr "labels.show-your-comments"))]
|
||||
[:div {:class (stl/css :icon)} i/arrow-refactor]]
|
||||
|
||||
[:& dropdown {:show options?
|
||||
:on-close #(reset! state* false)}
|
||||
[:& sidebar-options {:local local}]]
|
||||
[:& dropdown {:show options?
|
||||
:on-close #(reset! state* false)}
|
||||
[:& sidebar-options {:local local}]]
|
||||
|
||||
[:div {:class (stl/css :comments-section-content)}
|
||||
[:div {:class (stl/css :comments-section-content)}
|
||||
|
||||
(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-thread-click
|
||||
:users users}]
|
||||
(for [tgroup (rest tgroups)]
|
||||
[:& cmt/comment-thread-group
|
||||
{:group (first tgroups)
|
||||
{:group tgroup
|
||||
:on-thread-click on-thread-click
|
||||
:users users}]
|
||||
(for [tgroup (rest tgroups)]
|
||||
[:& cmt/comment-thread-group
|
||||
{:group tgroup
|
||||
:on-thread-click on-thread-click
|
||||
:users users
|
||||
:key (:page-id tgroup)}])]
|
||||
:users users
|
||||
:key (:page-id tgroup)}])]
|
||||
|
||||
[:div {:class (stl/css :thread-group-placeholder)}
|
||||
[:span {:class (stl/css :placeholder-icon)} i/comments-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "labels.no-comments-available")]])]]
|
||||
|
||||
|
||||
[:div.comments-section.comment-threads-section
|
||||
[:div.workspace-comment-threads-sidebar-header
|
||||
[:div.label (tr "labels.comments")]
|
||||
[:div.options {:on-click toggle-mode-selector}
|
||||
[:div.label (case (:mode local)
|
||||
(nil :all) (tr "labels.all")
|
||||
:yours (tr "labels.only-yours"))]
|
||||
[:div.icon i/arrow-down]]
|
||||
|
||||
[:& dropdown {:show options?
|
||||
:on-close #(reset! state* false)}
|
||||
[:& sidebar-options {:local local}]]]
|
||||
|
||||
(if (seq tgroups)
|
||||
[:div.thread-groups
|
||||
[:& cmt/comment-thread-group
|
||||
{:group (first tgroups)
|
||||
:on-thread-click on-thread-click
|
||||
:users users}]
|
||||
(for [tgroup (rest tgroups)]
|
||||
[:*
|
||||
[:hr]
|
||||
[:& cmt/comment-thread-group
|
||||
{:group tgroup
|
||||
:on-thread-click on-thread-click
|
||||
:users users
|
||||
:key (:page-id tgroup)}]])]
|
||||
|
||||
[:div.thread-groups-placeholder
|
||||
i/chat
|
||||
(tr "labels.no-comments-available")])])))
|
||||
[:div {:class (stl/css :thread-group-placeholder)}
|
||||
[:span {:class (stl/css :placeholder-icon)} i/comments-refactor]
|
||||
[:span {:class (stl/css :placeholder-label)}
|
||||
(tr "labels.no-comments-available")]])]]))
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
@include titleTipography;
|
||||
text-align: center;
|
||||
width: $s-184;
|
||||
color: var(--empty-message-foreground-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
height: $s-32;
|
||||
margin-right: $s-4;
|
||||
svg {
|
||||
height: $s-32;
|
||||
min-height: $s-32;
|
||||
width: $s-32;
|
||||
fill: var(--icon-foreground-hover);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,11 @@
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@include tabTitleTipography;
|
||||
margin-bottom: $s-16;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@@ -161,6 +163,7 @@
|
||||
.section-list-empty {
|
||||
@include titleTipography;
|
||||
@include flexCenter;
|
||||
color: var(--empty-message-foreground-color);
|
||||
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
@@ -32,8 +31,7 @@
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :nudge-option}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
profile (mf/deref refs/profile)
|
||||
(let [profile (mf/deref refs/profile)
|
||||
nudge (or (get-in profile [:props :nudge]) {:big 10 :small 1})
|
||||
update-big (mf/use-fn #(st/emit! (dw/update-nudge {:big %})))
|
||||
update-small (mf/use-fn #(st/emit! (dw/update-nudge {:small %})))
|
||||
@@ -43,45 +41,24 @@
|
||||
(->> (events/listen js/document EventType.KEYDOWN on-keydown)
|
||||
(partial events/unlistenByKey)))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.nudge-title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:class (stl/css :modal-msg)
|
||||
:for "nudge-small"} (tr "modals.small-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:id "nudge-small"
|
||||
:value (:small nudge)
|
||||
:on-change update-small}]]
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:class (stl/css :modal-msg)
|
||||
:for "nudge-big"} (tr "modals.big-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:id "nudge-big"
|
||||
:value (:big nudge)
|
||||
:on-change update-big}]]]]]
|
||||
|
||||
|
||||
[:div.nudge-modal-overlay
|
||||
[:div.nudge-modal-container
|
||||
[:div.nudge-modal-header
|
||||
[:p.nudge-modal-title (tr "modals.nudge-title")]
|
||||
[:button.modal-close-button {:on-click on-close} i/close]]
|
||||
[:div.nudge-modal-body
|
||||
[:div.input-wrapper
|
||||
[:span
|
||||
[:p.nudge-subtitle (tr "modals.small-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:value (:small nudge)
|
||||
:on-change update-small}]]]
|
||||
[:div.input-wrapper
|
||||
[:span
|
||||
[:p.nudge-subtitle (tr "modals.big-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:value (:big nudge)
|
||||
:on-change update-big}]]]]]])))
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-header)}
|
||||
[:h2 {:class (stl/css :modal-title)} (tr "modals.nudge-title")]
|
||||
[:button {:class (stl/css :modal-close-btn)
|
||||
:on-click on-close} i/close-refactor]]
|
||||
[:div {:class (stl/css :modal-content)}
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:class (stl/css :modal-msg)
|
||||
:for "nudge-small"} (tr "modals.small-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:id "nudge-small"
|
||||
:value (:small nudge)
|
||||
:on-change update-small}]]
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:class (stl/css :modal-msg)
|
||||
:for "nudge-big"} (tr "modals.big-nudge")]
|
||||
[:> numeric-input* {:min 0.01
|
||||
:id "nudge-big"
|
||||
:value (:big nudge)
|
||||
:on-change update-big}]]]]]))
|
||||
|
||||
@@ -8,33 +8,37 @@
|
||||
|
||||
.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;
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
label {
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
label {
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.comments :refer [comments-sidebar]]
|
||||
[app.main.ui.workspace.left-header :refer [left-header]]
|
||||
[app.main.ui.workspace.right-header :refer [right-header]]
|
||||
@@ -26,7 +23,6 @@
|
||||
[app.main.ui.workspace.sidebar.options :refer [options-toolbox]]
|
||||
[app.main.ui.workspace.sidebar.shortcuts :refer [shortcuts-container]]
|
||||
[app.main.ui.workspace.sidebar.sitemap :refer [sitemap]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -47,7 +43,6 @@
|
||||
(contains? layout :assets) :assets)
|
||||
shortcuts? (contains? layout :shortcuts)
|
||||
show-debug? (contains? layout :debug-panel)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
{on-pointer-down :on-pointer-down on-lost-pointer-capture :on-lost-pointer-capture on-pointer-move :on-pointer-move parent-ref :parent-ref size :size}
|
||||
(use-resize-hook :left-sidebar 275 275 500 :x false :left)
|
||||
@@ -65,25 +60,17 @@
|
||||
[:aside {:ref parent-ref
|
||||
:id "left-sidebar-aside"
|
||||
:data-size size
|
||||
:class (stl/css-case new-css-system
|
||||
:global/settings-bar (not new-css-system)
|
||||
:global/settings-bar-left (not new-css-system)
|
||||
:left-settings-bar true
|
||||
:class (stl/css-case :left-settings-bar true
|
||||
:global/two-row (<= size 300)
|
||||
:global/three-row (and (> size 300) (<= size 400))
|
||||
:global/four-row (> size 400))
|
||||
:style #js {"--width" (dm/str size "px")}}
|
||||
(when new-css-system
|
||||
[:& left-header {:file file :layout layout :project project :page-id page-id}])
|
||||
[:& left-header {:file file :layout layout :project project :page-id page-id}]
|
||||
[:div {:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (if ^boolean new-css-system
|
||||
(stl/css :resize-area)
|
||||
(dom/classnames :resize-area true))}]
|
||||
[:div {:class (if ^boolean new-css-system
|
||||
(stl/css :settings-bar-inside)
|
||||
(dom/classnames :settings-bar-inside true))}
|
||||
:class (stl/css :resize-area)}]
|
||||
[:div {:class (stl/css :settings-bar-inside)}
|
||||
(cond
|
||||
(true? shortcuts?)
|
||||
[:& shortcuts-container]
|
||||
@@ -92,64 +79,32 @@
|
||||
[:& debug-panel]
|
||||
|
||||
:else
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (stl/css :tabs-wrapper)}
|
||||
[:& tab-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse
|
||||
:class (stl/css :tab-spacing)}
|
||||
[:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class (stl/css :layers-tab)
|
||||
:style #js {"--height" (str size-pages "px")}}
|
||||
[:& sitemap {:layout layout
|
||||
:toggle-pages toggle-pages
|
||||
:show-pages? @show-pages?
|
||||
:size size-pages}]
|
||||
(when @show-pages?
|
||||
[:div {:class (stl/css :resize-area-horiz)
|
||||
:on-pointer-down on-pointer-down-pages
|
||||
:on-lost-pointer-capture on-lost-pointer-capture-pages
|
||||
:on-pointer-move on-pointer-move-pages}])
|
||||
[:& layers-toolbox {:size-parent size
|
||||
:size size-pages}]]]
|
||||
[:div {:class (stl/css :tabs-wrapper)}
|
||||
[:& tab-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse
|
||||
:class (stl/css :tab-spacing)}
|
||||
[:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class (stl/css :layers-tab)
|
||||
:style #js {"--height" (str size-pages "px")}}
|
||||
[:& sitemap {:layout layout
|
||||
:toggle-pages toggle-pages
|
||||
:show-pages? @show-pages?
|
||||
:size size-pages}]
|
||||
(when @show-pages?
|
||||
[:div {:class (stl/css :resize-area-horiz)
|
||||
:on-pointer-down on-pointer-down-pages
|
||||
:on-lost-pointer-capture on-lost-pointer-capture-pages
|
||||
:on-pointer-move on-pointer-move-pages}])
|
||||
[:& layers-toolbox {:size-parent size
|
||||
:size size-pages}]]]
|
||||
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]]
|
||||
|
||||
[:*
|
||||
[:button.collapse-sidebar
|
||||
{:on-click handle-collapse
|
||||
:aria-label (tr "workspace.sidebar.collapse")}
|
||||
i/arrow-slide]
|
||||
|
||||
[:& tabs-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse}
|
||||
|
||||
[:& tabs-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class :layers-tab
|
||||
:style #js {"--height" (str size-pages "px")}}
|
||||
[:& sitemap {:layout layout
|
||||
:toggle-pages toggle-pages
|
||||
:show-pages? @show-pages?
|
||||
:size size-pages}]
|
||||
(when @show-pages?
|
||||
[:div.resize-area-horiz
|
||||
{:on-pointer-down on-pointer-down-pages
|
||||
:on-lost-pointer-capture on-lost-pointer-capture-pages
|
||||
:on-pointer-move on-pointer-move-pages}])
|
||||
[:& layers-toolbox {:size-parent size}]]]
|
||||
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tabs-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]]))]]))
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]])]]))
|
||||
|
||||
;; --- Right Sidebar (Component)
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
(mf/html [:div {:class (stl/css :special-title)}
|
||||
file-name]))}
|
||||
(when-not local?
|
||||
[:span.tool-link.tooltip.tooltip-left {:alt "Open library file"}
|
||||
[:a {:class (dom/classnames true)
|
||||
[:span {:title "Open library file"}
|
||||
[:a {:class (stl/css :file-link)
|
||||
:href (str "#" url)
|
||||
:target "_blank"
|
||||
:on-click dom/stop-propagation}
|
||||
|
||||
@@ -147,23 +147,6 @@
|
||||
(t locale "workspace.undo.entry.unknown" value))))
|
||||
|
||||
(defn entry->icon [{:keys [type]}]
|
||||
(case type
|
||||
:page i/file-html
|
||||
:shape i/layers
|
||||
:rect i/box
|
||||
:circle i/circle
|
||||
:text i/text
|
||||
:path i/curve
|
||||
:frame i/artboard
|
||||
:group i/folder
|
||||
:color i/palette
|
||||
:typography i/titlecase
|
||||
:component i/component
|
||||
:media i/image
|
||||
:image i/image
|
||||
i/layers))
|
||||
|
||||
(defn entry->icon-refactor [{:keys [type]}]
|
||||
(case type
|
||||
:page i/document-refactor
|
||||
:shape i/svg-refactor
|
||||
@@ -310,9 +293,10 @@
|
||||
:on-pointer-enter #(reset! hover? true)
|
||||
:on-pointer-leave #(reset! hover? false)
|
||||
:on-click #(st/emit! (dwc/undo-to-index idx-entry))}
|
||||
|
||||
[:div {:class (stl/css :history-entry-summary)}
|
||||
[:div {:class (stl/css :history-entry-summary-icon)}
|
||||
(entry->icon-refactor entry)]
|
||||
(entry->icon entry)]
|
||||
[:div {:class (stl/css :history-entry-summary-text)} (entry->message locale entry)]
|
||||
(when (:detail entry)
|
||||
[:div {:class (stl/css-case :history-entry-summary-button true
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
.history-entry-empty-msg {
|
||||
@include titleTipography;
|
||||
color: var(--title-foreground-secondary);
|
||||
color: var(--empty-message-foreground-color);
|
||||
}
|
||||
|
||||
.history-entries {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -23,40 +22,24 @@
|
||||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
[]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
options (mf/deref refs/workspace-page-options)
|
||||
(let [options (mf/deref refs/workspace-page-options)
|
||||
on-change (mf/use-fn #(st/emit! (dw/change-canvas-color %)))
|
||||
on-open (mf/use-fn #(st/emit! (dwu/start-undo-transaction :options)))
|
||||
on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))]
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css :element-set)}
|
||||
[:div {:class (stl/css :element-title)}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title (tr "workspace.options.canvas-background")
|
||||
:class (stl/css :title-spacing-page)}]]
|
||||
[:div {:class (stl/css :element-content)}
|
||||
[:& color-row
|
||||
{:disable-gradient true
|
||||
:disable-opacity true
|
||||
:disable-image true
|
||||
:title (tr "workspace.options.canvas-background")
|
||||
:color {:color (get options :background clr/canvas)
|
||||
:opacity 1}
|
||||
:on-change on-change
|
||||
:on-open on-open
|
||||
:on-close on-close}]]]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title (tr "workspace.options.canvas-background")]
|
||||
[:div.element-set-content
|
||||
[:& color-row
|
||||
{:disable-gradient true
|
||||
:disable-opacity true
|
||||
:disable-image true
|
||||
:title (tr "workspace.options.canvas-background")
|
||||
:color {:color (get options :background clr/canvas)
|
||||
:opacity 1}
|
||||
:on-change on-change
|
||||
:on-open on-open
|
||||
:on-close on-close}]]])))
|
||||
[:div {:class (stl/css :element-set)}
|
||||
[:div {:class (stl/css :element-title)}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title (tr "workspace.options.canvas-background")
|
||||
:class (stl/css :title-spacing-page)}]]
|
||||
[:div {:class (stl/css :element-content)}
|
||||
[:& color-row
|
||||
{:disable-gradient true
|
||||
:disable-opacity true
|
||||
:disable-image true
|
||||
:title (tr "workspace.options.canvas-background")
|
||||
:color {:color (get options :background clr/canvas)
|
||||
:opacity 1}
|
||||
:on-change on-change
|
||||
:on-open on-open
|
||||
:on-close on-close}]]]))
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :as cb]
|
||||
[app.main.ui.components.color-bullet-new :as cbn]
|
||||
[app.main.ui.components.color-input :refer [color-input*]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||
@@ -43,10 +42,9 @@
|
||||
|
||||
(mf/defc color-row
|
||||
[{:keys [index color disable-gradient disable-opacity disable-image on-change
|
||||
on-reorder on-detach on-open on-close title on-remove
|
||||
on-reorder on-detach on-open on-close on-remove
|
||||
disable-drag on-focus on-blur select-only select-on-focus]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
file-colors (mf/deref refs/workspace-file-colors)
|
||||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
hover-detach (mf/use-state false)
|
||||
@@ -186,152 +184,87 @@
|
||||
(when (not= prev-color color)
|
||||
(modal/update-props! :colorpicker {:data (parse-color color)})))
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class (stl/css-case
|
||||
:color-data true
|
||||
:dnd-over-top (= (:over dprops) :top)
|
||||
:dnd-over-bot (= (:over dprops) :bot))
|
||||
:ref dref}
|
||||
[:span {:class (stl/css :color-info)}
|
||||
[:span {:class (stl/css-case :color-name-wrapper true
|
||||
:no-opacity (or disable-opacity
|
||||
(not opacity?))
|
||||
:library-name-wrapper library-color?
|
||||
:editing editing-text?
|
||||
:gradient-name-wrapper gradient-color?)}
|
||||
[:span {:class (stl/css :color-bullet-wrapper)}
|
||||
[:& cbn/color-bullet {:color (cond-> color
|
||||
(nil? color-name) (assoc
|
||||
:id nil
|
||||
:file-id nil))
|
||||
:mini? true
|
||||
:on-click handle-click-color}]]
|
||||
(cond
|
||||
;; Rendering a color with ID
|
||||
library-color?
|
||||
[:*
|
||||
[:div {:class (stl/css :color-name)
|
||||
:title (str color-name)}
|
||||
|
||||
(str color-name)]
|
||||
(when on-detach
|
||||
[:button
|
||||
{:class (stl/css :detach-btn)
|
||||
:title (tr "settings.detach")
|
||||
:on-pointer-enter #(reset! hover-detach true)
|
||||
:on-pointer-leave #(reset! hover-detach false)
|
||||
:on-click detach-value}
|
||||
i/detach-refactor])]
|
||||
|
||||
;; Rendering a gradient
|
||||
gradient-color?
|
||||
[:*
|
||||
[:div {:class (stl/css :color-name)}
|
||||
(uc/gradient-type->string (get-in color [:gradient :type]))]]
|
||||
|
||||
;; Rendering an image
|
||||
image-color?
|
||||
[:*
|
||||
[:div {:class (stl/css :color-name)}
|
||||
(tr "media.image")]]
|
||||
|
||||
;; Rendering a plain color
|
||||
:else
|
||||
[:span {:class (stl/css :color-input-wrapper)}
|
||||
[:> color-input* {:value (if multiple-colors?
|
||||
""
|
||||
(-> color :color cc/remove-hash))
|
||||
:placeholder (tr "settings.multiple")
|
||||
:className (stl/css :color-input)
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change handle-value-change}]])]
|
||||
|
||||
(when opacity?
|
||||
[:div {:class (stl/css :opacity-element-wrapper)}
|
||||
[:span {:class (stl/css :icon-text)}
|
||||
"%"]
|
||||
[:> numeric-input* {:value (-> color :opacity opacity->string)
|
||||
:className (stl/css :opacity-input)
|
||||
:placeholder "--"
|
||||
:select-on-focus select-on-focus
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change handle-opacity-change
|
||||
:min 0
|
||||
:max 100}]])]
|
||||
|
||||
(when (some? on-remove)
|
||||
[:button {:class (stl/css :remove-btn)
|
||||
:on-click on-remove} i/remove-refactor])
|
||||
(when select-only
|
||||
[:button {:class (stl/css :select-btn)
|
||||
:on-click handle-select}
|
||||
i/move-refactor])]
|
||||
|
||||
;; OLD CSS
|
||||
[:div.row-flex.color-data {:title title
|
||||
:class (dom/classnames
|
||||
:dnd-over-top (= (:over dprops) :top)
|
||||
:dnd-over-bot (= (:over dprops) :bot))
|
||||
:ref dref}
|
||||
[:& cb/color-bullet {:color (cond-> color
|
||||
(nil? color-name) (assoc
|
||||
:id nil
|
||||
:file-id nil))
|
||||
:on-click handle-click-color}]
|
||||
|
||||
[:div {:class (stl/css-case
|
||||
:color-data true
|
||||
:dnd-over-top (= (:over dprops) :top)
|
||||
:dnd-over-bot (= (:over dprops) :bot))
|
||||
:ref dref}
|
||||
[:span {:class (stl/css :color-info)}
|
||||
[:span {:class (stl/css-case :color-name-wrapper true
|
||||
:no-opacity (or disable-opacity
|
||||
(not opacity?))
|
||||
:library-name-wrapper library-color?
|
||||
:editing editing-text?
|
||||
:gradient-name-wrapper gradient-color?)}
|
||||
[:span {:class (stl/css :color-bullet-wrapper)}
|
||||
[:& cbn/color-bullet {:color (cond-> color
|
||||
(nil? color-name) (assoc
|
||||
:id nil
|
||||
:file-id nil))
|
||||
:mini? true
|
||||
:on-click handle-click-color}]]
|
||||
(cond
|
||||
;; Rendering a color with ID
|
||||
;; Rendering a color with ID
|
||||
library-color?
|
||||
[:*
|
||||
[:div.color-info
|
||||
[:div.color-name (str color-name)]]
|
||||
[:div {:class (stl/css :color-name)
|
||||
:title (str color-name)}
|
||||
|
||||
(str color-name)]
|
||||
(when on-detach
|
||||
[:div.element-set-actions-button
|
||||
{:on-pointer-enter #(reset! hover-detach true)
|
||||
[:button
|
||||
{:class (stl/css :detach-btn)
|
||||
:title (tr "settings.detach")
|
||||
:on-pointer-enter #(reset! hover-detach true)
|
||||
:on-pointer-leave #(reset! hover-detach false)
|
||||
:on-click detach-value}
|
||||
(if @hover-detach i/unchain i/chain)])]
|
||||
i/detach-refactor])]
|
||||
|
||||
;; Rendering a gradient
|
||||
;; Rendering a gradient
|
||||
gradient-color?
|
||||
[:*
|
||||
[:div.color-info
|
||||
[:div.color-name (uc/gradient-type->string (get-in color [:gradient :type]))]]
|
||||
(when select-only
|
||||
[:div.element-set-actions-button {:on-click handle-select}
|
||||
i/pointer-inner])]
|
||||
[:div {:class (stl/css :color-name)}
|
||||
(uc/gradient-type->string (get-in color [:gradient :type]))]]
|
||||
|
||||
;; Rendering a plain color/opacity
|
||||
:else
|
||||
;; Rendering an image
|
||||
image-color?
|
||||
[:*
|
||||
[:div.color-info
|
||||
[:> color-input* {:value (if multiple-colors?
|
||||
""
|
||||
(-> color :color cc/remove-hash))
|
||||
:placeholder (tr "settings.multiple")
|
||||
[:div {:class (stl/css :color-name)}
|
||||
(tr "media.image")]]
|
||||
|
||||
;; Rendering a plain color
|
||||
:else
|
||||
[:span {:class (stl/css :color-input-wrapper)}
|
||||
[:> color-input* {:value (if multiple-colors?
|
||||
""
|
||||
(-> color :color cc/remove-hash))
|
||||
:placeholder (tr "settings.multiple")
|
||||
:className (stl/css :color-input)
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change handle-value-change}]])]
|
||||
|
||||
(when opacity?
|
||||
[:div {:class (stl/css :opacity-element-wrapper)}
|
||||
[:span {:class (stl/css :icon-text)}
|
||||
"%"]
|
||||
[:> numeric-input* {:value (-> color :opacity opacity->string)
|
||||
:className (stl/css :opacity-input)
|
||||
:placeholder "--"
|
||||
:select-on-focus select-on-focus
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change handle-value-change}]]
|
||||
:on-change handle-opacity-change
|
||||
:min 0
|
||||
:max 100}]])]
|
||||
|
||||
(when (and (not disable-opacity)
|
||||
(not (:gradient color)))
|
||||
[:div.input-element
|
||||
{:class (dom/classnames :percentail (not= (:opacity color) :multiple))}
|
||||
[:> numeric-input* {:value (-> color :opacity opacity->string)
|
||||
:placeholder (tr "settings.multiple")
|
||||
:select-on-focus select-on-focus
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change handle-opacity-change
|
||||
:min 0
|
||||
:max 100}]])
|
||||
(when select-only
|
||||
[:div.element-set-actions-button {:on-click handle-select}
|
||||
i/pointer-inner])])
|
||||
(when (some? on-remove)
|
||||
[:div.element-set-actions-button.remove {:on-click on-remove} i/minus])])
|
||||
(when (some? on-remove)
|
||||
[:button {:class (stl/css :remove-btn)
|
||||
:on-click on-remove} i/remove-refactor])
|
||||
(when select-only
|
||||
[:button {:class (stl/css :select-btn)
|
||||
:on-click handle-select}
|
||||
i/move-refactor])]
|
||||
|
||||
))
|
||||
|
||||
|
||||
@@ -8,155 +8,6 @@
|
||||
|
||||
.color-data {
|
||||
@include flexRow;
|
||||
.color-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $s-2;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--input-details-color);
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
.color-name-wrapper {
|
||||
@extend .input-element;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
padding: 0;
|
||||
margin-right: 0;
|
||||
gap: $s-4;
|
||||
input {
|
||||
padding: 0;
|
||||
}
|
||||
.color-bullet-wrapper {
|
||||
height: $s-28;
|
||||
padding: 0 $s-2 0 $s-8;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
background-color: transparent;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
.color-name {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-28;
|
||||
padding-left: $s-6;
|
||||
border-radius: $br-8;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
color: var(--input-foreground-color-active);
|
||||
}
|
||||
.detach-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-28;
|
||||
width: $s-28;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
display: none;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
.color-input-wrapper {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-28;
|
||||
padding: 0 $s-0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--input-foreground-color);
|
||||
border-radius: $br-0;
|
||||
}
|
||||
&.no-opacity {
|
||||
border-radius: $br-8;
|
||||
.color-input-wrapper {
|
||||
border-radius: $br-8;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--input-background-color-hover);
|
||||
border: $s-1 solid var(--input-background-color-hover);
|
||||
.color-bullet-wrapper,
|
||||
.color-name,
|
||||
.detach-btn,
|
||||
.color-input-wrapper {
|
||||
background-color: var(--input-background-color-hover);
|
||||
}
|
||||
.detach-btn {
|
||||
display: flex;
|
||||
svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
&.editing {
|
||||
background-color: var(--input-background-color-active);
|
||||
.color-bullet-wrapper,
|
||||
.color-name,
|
||||
.detach-btn,
|
||||
.color-input-wrapper {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
|
||||
&.editing {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
.gradient-name-wrapper {
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
.color-name {
|
||||
@include flexRow;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
}
|
||||
}
|
||||
.library-name-wrapper {
|
||||
border-radius: $br-8;
|
||||
}
|
||||
.opacity-element-wrapper {
|
||||
@extend .input-element;
|
||||
width: $s-60;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
.opacity-input {
|
||||
padding: 0;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
min-width: $s-28;
|
||||
}
|
||||
.icon-text {
|
||||
@include flexCenter;
|
||||
height: $s-32;
|
||||
margin-right: $s-4;
|
||||
padding-top: $s-2;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.detach-btn,
|
||||
.select-btn {
|
||||
background-color: transparent;
|
||||
svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.remove-btn,
|
||||
.select-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
|
||||
&.dnd-over-top {
|
||||
border-top: $s-1 solid var(--layer-row-foreground-color-drag);
|
||||
@@ -165,3 +16,155 @@
|
||||
border-bottom: $s-1 solid var(--layer-row-foreground-color-drag);
|
||||
}
|
||||
}
|
||||
|
||||
.color-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $s-2;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--input-details-color);
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
|
||||
.color-name-wrapper {
|
||||
@extend .input-element;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
padding: 0;
|
||||
margin-right: 0;
|
||||
gap: $s-4;
|
||||
input {
|
||||
padding: 0;
|
||||
}
|
||||
.color-bullet-wrapper {
|
||||
height: $s-28;
|
||||
padding: 0 $s-2 0 $s-8;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
background-color: transparent;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
.color-name {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-28;
|
||||
padding-left: $s-6;
|
||||
border-radius: $br-8;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
color: var(--input-foreground-color-active);
|
||||
}
|
||||
.detach-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-28;
|
||||
width: $s-28;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
display: none;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
.color-input-wrapper {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-28;
|
||||
padding: 0 $s-0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--input-foreground-color);
|
||||
border-radius: $br-0;
|
||||
}
|
||||
&.no-opacity {
|
||||
border-radius: $br-8;
|
||||
.color-input-wrapper {
|
||||
border-radius: $br-8;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--input-background-color-hover);
|
||||
border: $s-1 solid var(--input-background-color-hover);
|
||||
.color-bullet-wrapper,
|
||||
.color-name,
|
||||
.detach-btn,
|
||||
.color-input-wrapper {
|
||||
background-color: var(--input-background-color-hover);
|
||||
}
|
||||
.detach-btn {
|
||||
display: flex;
|
||||
svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
&.editing {
|
||||
background-color: var(--input-background-color-active);
|
||||
.color-bullet-wrapper,
|
||||
.color-name,
|
||||
.detach-btn,
|
||||
.color-input-wrapper {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
|
||||
&.editing {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
.gradient-name-wrapper {
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
.color-name {
|
||||
@include flexRow;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
}
|
||||
}
|
||||
.library-name-wrapper {
|
||||
border-radius: $br-8;
|
||||
}
|
||||
.opacity-element-wrapper {
|
||||
@extend .input-element;
|
||||
width: $s-60;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
.opacity-input {
|
||||
padding: 0;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
min-width: $s-28;
|
||||
}
|
||||
.icon-text {
|
||||
@include flexCenter;
|
||||
height: $s-32;
|
||||
margin-right: $s-4;
|
||||
padding-top: $s-2;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.detach-btn,
|
||||
.select-btn {
|
||||
background-color: transparent;
|
||||
svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remove-btn,
|
||||
.select-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user