diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6cef7d76f..b57665d55 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,9 +1,9 @@
{
- "files.exclude": {
- "**/.clj-kondo": true,
- "**/.cpcache": true,
- "**/.lsp": true,
- "**/.shadow-cljs": true,
- "**/node_modules": true
- }
+ "files.exclude": {
+ "**/.clj-kondo": true,
+ "**/.cpcache": true,
+ "**/.lsp": true,
+ "**/.shadow-cljs": true,
+ "**/node_modules": true
+ }
}
diff --git a/frontend/resources/images/icons/msg-error-refactor.svg b/frontend/resources/images/icons/msg-error-refactor.svg
new file mode 100644
index 000000000..a5871b29f
--- /dev/null
+++ b/frontend/resources/images/icons/msg-error-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/msg-neutral-refactor.svg b/frontend/resources/images/icons/msg-neutral-refactor.svg
new file mode 100644
index 000000000..63dec6c2b
--- /dev/null
+++ b/frontend/resources/images/icons/msg-neutral-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/msg-success-refactor.svg b/frontend/resources/images/icons/msg-success-refactor.svg
new file mode 100644
index 000000000..f7cf5e6de
--- /dev/null
+++ b/frontend/resources/images/icons/msg-success-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/msg-warning-refactor.svg b/frontend/resources/images/icons/msg-warning-refactor.svg
new file mode 100644
index 000000000..df700ade5
--- /dev/null
+++ b/frontend/resources/images/icons/msg-warning-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/tree-refactor.svg b/frontend/resources/images/icons/tree-refactor.svg
new file mode 100644
index 000000000..b9405eaac
--- /dev/null
+++ b/frontend/resources/images/icons/tree-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/user-refactor.svg b/frontend/resources/images/icons/user-refactor.svg
new file mode 100644
index 000000000..0d763101a
--- /dev/null
+++ b/frontend/resources/images/icons/user-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss
index b9d9d85a7..76cf29754 100644
--- a/frontend/resources/styles/common/refactor/basic-rules.scss
+++ b/frontend/resources/styles/common/refactor/basic-rules.scss
@@ -66,7 +66,8 @@
}
}
&:global(.disabled),
- &[disabled] {
+ &[disabled],
+ &:disabled {
background-color: var(--button-background-color-disabled);
border: $s-1 solid var(--button-border-color-disabled);
color: var(--button-foreground-color-disabled);
@@ -107,7 +108,8 @@
}
}
&:global(.disabled),
- &[disabled] {
+ &[disabled],
+ &:disabled {
background-color: var(--button-background-color-disabled);
border: $s-1 solid var(--button-border-color-disabled);
color: var(--button-foreground-color-disabled);
@@ -147,7 +149,8 @@
}
}
&:global(.disabled),
- &[disabled] {
+ &[disabled],
+ &:disabled {
color: var(--button-foreground-color-disabled);
cursor: unset;
pointer-events: none;
@@ -202,9 +205,9 @@
.button-disabled {
@include buttonStyle;
@include flexCenter;
- background-color: var(--button-disabled-background-color-rest);
- border: $s-1 solid var(--button-disabled-border-color-rest);
- color: var(--button-disabled-foreground-color-rest);
+ background-color: var(--button-background-color-disabled);
+ border: $s-1 solid var(--button-border-color-disabled);
+ color: var(--button-foreground-color-disabled);
cursor: unset;
}
@@ -254,7 +257,6 @@
}
// INPUTS
-
.input-base {
@include removeInputStyle;
@include titleTipography;
@@ -313,9 +315,11 @@
input {
@extend .input-base;
}
+
::placeholder {
color: var(--input-placeholder-color);
}
+
&:hover {
span {
color: var(--input-foreground-color);
@@ -327,9 +331,48 @@
}
}
+.input-element-label {
+ @include titleTipography;
+ display: flex;
+ align-items: flex-start;
+ padding: 0;
+ input {
+ @extend .input-base;
+ padding-left: $s-8;
+ display: flex;
+ align-items: flex-start;
+ height: $s-32;
+ box-sizing: border-box;
+ width: 100%;
+ margin: 0;
+ border-radius: $br-8;
+ border: $s-1 solid var(--input-background-color);
+ color: var(--input-foreground-color-active);
+ background-color: var(--input-background-color);
+ }
+ ::placeholder {
+ color: var(--input-placeholder-color);
+ }
+ &:hover {
+ input {
+ color: var(--input-foreground-color-active);
+ background-color: var(--input-background-color-hover);
+ }
+ }
+
+ &:focus-within,
+ &:active {
+ input {
+ color: var(--input-foreground-color-active);
+ background-color: var(--input-background-color-active);
+ border: $s-1 solid var(--input-border-color-active);
+ }
+ }
+}
+
.disabled-input {
background-color: var(--input-background-color-disabled);
- border: 1px solid var(--input-border-color-disabled);
+ border: $s-1 solid var(--input-border-color-disabled);
color: var(--input-foreground-color-disabled);
input {
pointer-events: none;
@@ -348,17 +391,40 @@
min-width: $s-16;
min-height: $s-16;
border-radius: $br-6;
- background-color: var(--input-background-color);
+ background-color: var(--input-checkbox-background-color-rest);
+ border: $s-1 solid var(--input-checkbox-background-color-rest);
svg {
display: none;
}
+ &:hover {
+ border-color: var(--input-checkbox-border-color-hover);
+ }
+ &:focus {
+ border-color: var(--input-checkbox-border-color-focus);
+ }
&:global(.checked) {
background-color: var(--input-border-color-active);
+ border-color: var(--input-checkbox-border-color-active);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
}
}
+ &:global(.intermediate) {
+ background-color: var(--input-checkbox-background-color-intermediate);
+ border-color: var(--input-checkbox-border-color-active);
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--input-details-color);
+ }
+ }
+ &:global(.unchecked) {
+ background-color: var(--input-checkbox-background-color-rest);
+ border: $s-1 solid var(--input-checkbox-background-color-rest);
+ svg {
+ display: none;
+ }
+ }
}
.input-checkbox {
@@ -376,6 +442,53 @@
input {
margin: 0;
}
+ &:hover {
+ span {
+ border-color: var(--input-checkbox-border-color-hover);
+ }
+ }
+ }
+}
+
+.input-with-label {
+ display: flex;
+ flex-direction: column;
+ label {
+ @include titleTipography;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ min-height: $s-16;
+ color: var(--input-foreground-color-active);
+ }
+
+ input {
+ @extend .input-base;
+ @include titleTipography;
+ border-radius: $br-8;
+ height: $s-32;
+ min-height: $s-32;
+ margin-top: $s-8;
+ background-color: var(--input-background-color);
+ border: $s-1 solid var(--input-background-color);
+ color: var(--input-foreground-color-active);
+ &:focus-within,
+ &:active {
+ input {
+ color: var(--input-foreground-color-active);
+ }
+ background-color: var(--input-background-color-active);
+ border: $s-1 solid var(--input-border-color-active);
+ }
+ }
+ &:global(.disabled) {
+ @extend .disabled-input;
+ }
+
+ &:global(.invalid) {
+ input {
+ border: $s-1 solid var(--input-border-color-error);
+ }
}
}
@@ -392,6 +505,83 @@
background-color: var(--modal-background-color);
}
+.modal-overlay-base {
+ @include flexCenter;
+ position: fixed;
+ left: 0;
+ top: 0;
+ height: 100%;
+ width: 100%;
+ z-index: $z-index-modal;
+ background-color: var(--color-background-subtle);
+}
+
+.modal-container-base {
+ position: relative;
+ padding: $s-32;
+ border-radius: $br-8;
+ background-color: var(--modal-background-color);
+ min-width: $s-364;
+ min-height: $s-192;
+ max-width: $s-512;
+ max-height: $s-512;
+}
+
+.modal-close-btn-base {
+ @extend .button-tertiary;
+ position: absolute;
+ top: $s-8;
+ right: $s-6;
+ height: $s-32;
+ width: $s-28;
+ svg {
+ @extend .button-icon;
+ }
+}
+
+.modal-hint-base {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+ border-top: $s-1 solid var(--modal-hint-border-color);
+ border-bottom: $s-1 solid var(--modal-hint-border-color);
+}
+
+.modal-action-btns {
+ display: flex;
+ justify-content: flex-end;
+ gap: $s-16;
+}
+
+.modal-cancel-btn {
+ @extend .button-secondary;
+ @include tabTitleTipography;
+ padding: $s-8 $s-24;
+ border-radius: $br-8;
+ height: $s-32;
+ margin: 0;
+}
+
+.modal-accept-btn {
+ @extend .button-primary;
+ @include tabTitleTipography;
+ padding: $s-8 $s-24;
+ border-radius: $br-8;
+ height: $s-32;
+ margin: 0;
+}
+
+.modal-danger-btn {
+ @extend .button-primary;
+ @include tabTitleTipography;
+ padding: $s-8 $s-24;
+ border-radius: $br-8;
+ height: $s-32;
+ margin: 0;
+ background-color: var(--modal-button-background-color-error);
+ border: $s-1 solid var(--modal-button-background-color-error);
+ color: var(--modal-button-foreground-color-error);
+}
+
// UI ELEMENTS
.asset-element {
@include titleTipography;
@@ -641,3 +831,13 @@
background-color: var(--menu-background-color);
color: var(--menu-foreground-color);
}
+
+.select-wrapper {
+ @include titleTipography;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: normal;
+ width: 100%;
+ overflow: hidden;
+}
diff --git a/frontend/resources/styles/common/refactor/color-defs.scss b/frontend/resources/styles/common/refactor/color-defs.scss
index 41b0077ce..b1c0a2b0f 100644
--- a/frontend/resources/styles/common/refactor/color-defs.scss
+++ b/frontend/resources/styles/common/refactor/color-defs.scss
@@ -21,9 +21,9 @@
// NOTIFICATION
--dark-ok-color: var(--strong-green);
- --dark-warning-color: #ff9b49;
+ --dark-warning-color: #ff6432;
--dark-pending-color: var(--lilac);
- --dark-error-color: #ff4986;
+ --dark-error-color: #ec1f1f;
// LIGHT
--light-gray-1: #fff;
diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss
index 829364a1f..cbaaba240 100644
--- a/frontend/resources/styles/common/refactor/design-tokens.scss
+++ b/frontend/resources/styles/common/refactor/design-tokens.scss
@@ -7,6 +7,7 @@
.light,
.default {
+ // BASE COLORS
--canvas-background-color: var(--color-background-primary);
--canvas-fill-color: var(--canvas-color);
@@ -15,7 +16,6 @@
--panel-title-background-color: var(--color-background-secondary);
// BUTTONS
-
--button-foreground-hover: var(--color-accent-primary);
--button-background-color-focus: var(--color-background-secondary);
--button-foreground-color-focus: var(--color-foreground-primary);
@@ -88,22 +88,19 @@
--constraint-widget-background-color: var(--color-background-tertiary);
--constraint-center-area-background-color: var(--color-background-primary);
- // ICONS
- --icon-foreground: var(--color-foreground-secondary);
- --icon-foreground-hover: var(--color-foreground-primary);
-
- --link-foreground-color: var(--color-accent-primary);
-
+ // TABS
--tab-background-color-hover: var(--color-background-primary);
--tab-background-color-selected: var(--color-background-quaternary);
--tab-foreground-color: var(--color-foreground-secondary);
--tab-foreground-color-hover: var(--color-foreground-primary);
--tab-foreground-color-selected: var(--color-accent-primary);
+ // SECTION TITLE
--title-background-color: var(--color-background-primary);
--title-foreground-color: var(--color-foreground-secondary);
--title-foreground-color-hover: var(--color-foreground-primary);
+ // LAYER ELEMENT
--layer-row-background-color: var(--color-background-primary);
--layer-row-background-color-hover: var(--color-background-secondary);
--layer-row-background-color-selected: var(--color-background-quaternary);
@@ -118,9 +115,26 @@
--layer-child-row-foreground-color: var(--color-foreground-secondary);
--layer-row-component-foreground-color: var(--color-accent-secondary);
- --search-bar-background-color: var(--color-background-primary);
- --search-bar-input-background-color: var(--color-background-tertiary);
- --search-bar-input-border-color: var(--color-background-tertiary);
+ // PALETTE & COLOR BULLET
+ --palette-background-color: var(--color-background-primary);
+ --palette-btn-background-color-selected: var(--color-background-secondary);
+ --palette-btn-border-color-selected: var(--color-background-quaternary);
+ --palette-btn-foreground-color-selected: var(--color-accent-primary);
+ --palette-text-color: var(--color-foreground-secondary);
+ --palette-text-color-selected: var(--color-foreground-primary);
+ --palette-text-background-color: var(--color-background-tertiary);
+ --palette-text-background-color-hover: var(--color-background-quaternary);
+ --palette-button-shadow-initial: var(--color-background-primary);
+ --palette-button-shadow-final: transparent;
+ --palette-handler-background-color: var(--color-background-quaternary);
+
+ --color-bullet-background-color: var(--white); // We don't want this color to change with palette
+ --color-bullet-border-color: var(--color-background-quaternary);
+ --color-bullet-border-color-selected: var(--color-accent-primary);
+
+ // ICONS
+ --icon-foreground: var(--color-foreground-secondary);
+ --icon-foreground-hover: var(--color-foreground-primary);
// INPUTS, SELECTS, DROPDOWNS
--input-background-color: var(--color-background-tertiary);
@@ -136,7 +150,14 @@
--input-background-color-disabled: var(--color-background-primary);
--input-foreground-color-disabled: var(--color-foreground-secondary);
--input-border-color-disabled: var(--color-background-quaternary);
+ --input-border-color-error: var(--error-color);
--input-details-color: var(--color-background-primary);
+ --input-checkbox-background-color-rest: var(--color-background-quaternary);
+ --input-checkbox-border-color-active: var(--color-background-quaternary);
+ --input-checkbox-border-color-focus: var(--color-accent-primary);
+ --input-checkbox-border-color: var(--color-background-secondary);
+ --input-checkbox-border-color-hover: var(--color-accent-primary-muted);
+ --input-checkbox-background-color-intermediate: var(--color-foreground-secondary);
--menu-background-color: var(--color-background-tertiary);
--menu-foreground-color: var(--color-foreground-primary);
@@ -156,32 +177,12 @@
--menu-foreground-color-disabled: var(--color-foreground-secondary);
--menu-border-color-disabled: var(--color-background-quaternary);
- --pill-background-color: var(--color-background-tertiary);
- --pill-foreground-color: var(--color-foreground-primary);
-
- --tag-background-color: var(--color-accent-primary);
-
- --palette-background-color: var(--color-background-primary);
- --palette-btn-background-color-selected: var(--color-background-secondary);
- --palette-btn-border-color-selected: var(--color-background-quaternary);
- --palette-btn-foreground-color-selected: var(--color-accent-primary);
- --palette-text-color: var(--color-foreground-secondary);
- --palette-text-color-selected: var(--color-foreground-primary);
- --palette-text-background-color: var(--color-background-tertiary);
- --palette-text-background-color-hover: var(--color-background-quaternary);
- --palette-button-shadow-initial: var(--color-background-primary);
- --palette-button-shadow-final: transparent;
-
--context-menu-background-color: var(--color-background-tertiary);
--context-menu-foreground-color: var(--color-foreground-secondary);
--context-menu-background-color-selected: var(--color-background-quaternary);
--context-menu-foreground-color-selected: var(--color-foreground-primary);
- --color-bullet-background-color: var(--white); // We don't want this color to change with palette
- --color-bullet-border-color: var(--color-background-quaternary);
- --color-bullet-border-color-selected: var(--color-accent-primary);
- --palette-handler-background-color: var(--color-background-quaternary);
-
+ // ASSETS
--assets-title-background-color: var(--color-background-primary);
--assets-item-background-color: var(--color-background-tertiary);
--assets-item-background-color-hover: var(--color-background-quaternary);
@@ -220,19 +221,10 @@
--empty-message-background-color: var(--color-background-tertiary);
--empty-message-foreground-color: var(--color-foreground-secondary);
- --status-ok-background-color: var(--ok-color);
- --status-warning-background-color: var(--warning-color);
- --status-pending-background-color: var(--pending-color);
- --status-error-background-color: var(--error-color);
- --status-icon-foreground-color: var(--color-background-primary);
-
--user-count-background-color: var(--color-background-secondary);
--user-count-foreground-color: var(--color-accent-primary);
- --modal-background-color: var(--color-background-primary);
- --modal-foreground-color: var(--color-foreground-primary);
- --modal-foreground-color-secondary: var(--color-foreground-secondary);
-
+ // COLORPICKER
--colorpicker-details-color: var(--color-background-quaternary);
--colorpicker-details-color-selected: var(--color-accent-primary);
--colorpicker-handlers-color: var(--color-foreground-primary);
@@ -259,4 +251,43 @@
--grid-editor-line-color: var(--color-foreground-tertiary);
--grid-editor-plus-btn-foreground: var(--white);
--grid-editor-plus-btn-background: var(--color-foreground-tertiary);
+
+ // MODALS
+ --modal-background-color: var(--color-background-primary);
+ --modal-title-foreground-color: var(--color-foreground-primary);
+ --modal-text-foreground-color: var(--color-foreground-secondary);
+ --modal-hint-border-color: var(--color-background-quaternary);
+ --modal-button-background-color-error: var(--error-color);
+ --modal-button-foreground-color-error: var(--color-foreground-primary);
+ --modal-link-foreground-color: var(--color-accent-primary);
+ --modal-border-color: var(--color-background-quaternary);
+
+ // ALERTS & STATUS
+ --alert-background-color-ok: var(--ok-color);
+ --alert-foreground-color-ok: var(--color-background-secondary);
+ --alert-background-color-warning: var(--warning-color);
+ --alert-foreground-color-warning: var(--color-foreground-primary);
+ --alert-background-color-error: var(--error-color);
+ --alert-foreground-color-error: var(--color-foreground-primary);
+ --alert-background-color-neutral: var(--color-background-quaternary);
+ --alert-foreground-color-neutral: var(--color-foreground-secondary);
+ --alert-foreground-color-neutral-active: var(--color-foreground-primary);
+
+ --status-ok-background-color: var(--ok-color);
+ --status-warning-background-color: var(--warning-color);
+ --status-pending-background-color: var(--pending-color);
+ --status-error-background-color: var(--error-color);
+ --status-icon-foreground-color: var(--color-background-primary);
+
+ // INTERFACE ELEMENTS
+ --search-bar-background-color: var(--color-background-primary);
+ --search-bar-input-background-color: var(--color-background-tertiary);
+ --search-bar-input-border-color: var(--color-background-tertiary);
+
+ --pill-background-color: var(--color-background-tertiary);
+ --pill-foreground-color: var(--color-foreground-primary);
+
+ --tag-background-color: var(--color-accent-primary);
+
+ --link-foreground-color: var(--color-accent-primary);
}
diff --git a/frontend/resources/styles/common/refactor/fonts.scss b/frontend/resources/styles/common/refactor/fonts.scss
index ebc5b5e15..ef4df7c8c 100644
--- a/frontend/resources/styles/common/refactor/fonts.scss
+++ b/frontend/resources/styles/common/refactor/fonts.scss
@@ -7,24 +7,15 @@
@use "sass:math";
@import "common/dependencies/mixin";
-// Font sizes
-$fs10: 0.625rem;
-$fs-11: 0.688rem;
-$fs12: 0.75rem;
-$fs14: 0.875rem;
-
// Typography scale
$fs-base: 16;
-$fs-9: math.div(9, $fs-base) + rem;
$fs-10: math.div(10, $fs-base) + rem;
+$fs-11: 0.688rem;
$fs-12: math.div(12, $fs-base) + rem;
$fs-14: math.div(14, $fs-base) + rem;
$fs-16: math.div(16, $fs-base) + rem;
-$fs-19: math.div(19, $fs-base) + rem;
-$fs-25: math.div(25, $fs-base) + rem;
-$fs-33: math.div(33, $fs-base) + rem;
-$fs-44: math.div(44, $fs-base) + rem;
+$fs-24: math.div(24, $fs-base) + rem;
// Font weight
$fw400: 400; // Regular (CSS value: 'normal')
diff --git a/frontend/resources/styles/common/refactor/mixins.scss b/frontend/resources/styles/common/refactor/mixins.scss
index 744e2abcd..d5e088c12 100644
--- a/frontend/resources/styles/common/refactor/mixins.scss
+++ b/frontend/resources/styles/common/refactor/mixins.scss
@@ -49,13 +49,20 @@
line-height: 1.2;
}
-@mixin titleBigTipography {
+@mixin medTitleTipography {
font-family: "worksans", sans-serif;
font-size: $fs-14;
font-weight: $fw400;
line-height: 1.2;
}
+@mixin bigTitleTipography {
+ font-family: "worksans", sans-serif;
+ font-size: $fs-24;
+ font-weight: $fw400;
+ line-height: 1.2;
+}
+
@mixin textEllipsis {
max-width: 99%;
overflow: hidden;
diff --git a/frontend/resources/styles/common/refactor/shadows.scss b/frontend/resources/styles/common/refactor/shadows.scss
index bcc0f1718..ec1e172d2 100644
--- a/frontend/resources/styles/common/refactor/shadows.scss
+++ b/frontend/resources/styles/common/refactor/shadows.scss
@@ -7,3 +7,7 @@
@mixin menuShadow {
box-shadow: 0px 0px $s-12 0px var(--menu-shadow-color);
}
+
+@mixin alertShadow {
+ box-shadow: 0px $s-4 $s-4 var(--menu-shadow-color);
+}
diff --git a/frontend/resources/styles/common/refactor/spacing.scss b/frontend/resources/styles/common/refactor/spacing.scss
index b956d7cd1..2b046700c 100644
--- a/frontend/resources/styles/common/refactor/spacing.scss
+++ b/frontend/resources/styles/common/refactor/spacing.scss
@@ -70,12 +70,17 @@ $s-284: calc(var(--s-4) * 71);
$s-300: calc(var(--s-4) * 75);
$s-320: calc(var(--s-4) * 80);
$s-348: calc(var(--s-4) * 87);
+$s-356: calc(var(--s-4) * 89);
+$s-364: calc(var(--s-4) * 91);
$s-380: calc(var(--s-4) * 95);
$s-400: calc(var(--s-4) * 100);
+$s-408: calc(var(--s-4) * 102);
+$s-440: calc(var(--s-4) * 110);
$s-480: calc(var(--s-4) * 120);
$s-500: calc(var(--s-4) * 125);
$s-512: calc(var(--s-4) * 128);
$s-520: calc(var(--s-4) * 130);
+$s-640: calc(var(--s-4) * 160);
$s-664: calc(var(--s-4) * 166);
$s-712: calc(var(--s-4) * 178);
$s-736: calc(var(--s-4) * 184);
diff --git a/frontend/resources/styles/common/refactor/z-index.scss b/frontend/resources/styles/common/refactor/z-index.scss
index 7e20a36f1..fed8066ce 100644
--- a/frontend/resources/styles/common/refactor/z-index.scss
+++ b/frontend/resources/styles/common/refactor/z-index.scss
@@ -11,3 +11,4 @@ $z-index-4: 4; // modal
$z-index-10: 10;
$z-index-20: 20;
$z-index-modal: 30; // When refactor finish we can reduce this number,
+$z-index-alert: 40; // When refactor finish we can reduce this number,
diff --git a/frontend/resources/styles/main/partials/colorpicker.scss b/frontend/resources/styles/main/partials/colorpicker.scss
index 2ad36757d..e70546d65 100644
--- a/frontend/resources/styles/main/partials/colorpicker.scss
+++ b/frontend/resources/styles/main/partials/colorpicker.scss
@@ -315,7 +315,7 @@
.slider-selector.opacity {
grid-area: "opacity";
- align-self: start;
+ align-self: flex-start;
}
}
diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss
index 7498ef5b2..7615ef663 100644
--- a/frontend/resources/styles/main/partials/modal.scss
+++ b/frontend/resources/styles/main/partials/modal.scss
@@ -1522,7 +1522,7 @@
flex-grow: 1;
display: flex;
flex-direction: column;
- justify-content: start;
+ justify-content: flex-start;
align-items: flex-start;
row-gap: 1.5rem;
.custom-input {
diff --git a/frontend/src/app/main/ui/alert.cljs b/frontend/src/app/main/ui/alert.cljs
index 1acb30eb8..7511c390b 100644
--- a/frontend/src/app/main/ui/alert.cljs
+++ b/frontend/src/app/main/ui/alert.cljs
@@ -5,9 +5,11 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.alert
+ (:require-macros [app.main.style :as stl])
(: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]]
@@ -25,7 +27,8 @@
hint
accept-label
accept-style] :as props}]
- (let [on-accept (or on-accept identity)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ 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)
@@ -47,29 +50,54 @@
(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.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 {: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.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 {: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-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.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}]]]]])))
diff --git a/frontend/src/app/main/ui/alert.scss b/frontend/src/app/main/ui/alert.scss
new file mode 100644
index 000000000..fd7eee9a4
--- /dev/null
+++ b/frontend/src/app/main/ui/alert.scss
@@ -0,0 +1,51 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+ &.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-msg,
+ .modal-scd-msg,
+ .modal-hint,
+ .modal-subtitle {
+ @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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/components/forms.cljs b/frontend/src/app/main/ui/components/forms.cljs
index 64f4e4103..a29a3f001 100644
--- a/frontend/src/app/main/ui/components/forms.cljs
+++ b/frontend/src/app/main/ui/components/forms.cljs
@@ -5,9 +5,11 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.components.forms
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
+ [app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
@@ -24,11 +26,13 @@
(def use-form fm/use-form)
(mf/defc input
- [{:keys [label help-icon disabled form hint trim children data-test on-change-value] :as props}]
- (let [input-type (get props :type "text")
+ [{:keys [label help-icon disabled form hint trim children data-test on-change-value placeholder] :as props}]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ input-type (get props :type "text")
input-name (get props :name)
more-classes (get props :class)
auto-focus? (get props :auto-focus? false)
+ placeholder (or placeholder label)
form (or form (mf/use-ctx form-ctx))
@@ -43,6 +47,7 @@
touched? (get-in @form [:touched input-name])
error (get-in @form [:errors input-name])
+
value (get-in @form [:data input-name] "")
help-icon' (cond
@@ -71,6 +76,13 @@
:input-radio is-radio?
:input-checkbox is-checkbox?))
+ new-classes (dm/str more-classes " "
+ (stl/css-case
+ :input-wrapper true
+ :global/invalid (and touched? error)
+ :checkbox is-checkbox?
+ :global/disabled disabled))
+
swap-text-password
(fn []
(swap! type' (fn [input-type]
@@ -96,6 +108,8 @@
(when-not (get-in @form [:touched input-name])
(swap! form assoc-in [:touched input-name] true)))
+
+
props (-> props
(dissoc :help-icon :form :trim :children)
(assoc :id (name input-name)
@@ -104,7 +118,7 @@
:on-click (when (or is-radio? is-checkbox?) on-click)
:on-focus on-focus
:on-blur on-blur
- :placeholder label
+ :placeholder placeholder
:on-change on-change
:type @type'
:tab-index "0")
@@ -113,30 +127,67 @@
"aria-describedby" (dm/str "error-" input-name)))
(obj/clj->props))]
- [:div
- {:class klass}
- [:*
- [:> :input props]
- (cond
- (some? label)
- [:label {:for (name input-name)} label]
+ (if new-css-system
+ [:div {:class new-classes}
+ [:*
+ (cond
+ (some? label)
+ [:label {:class (stl/css-case :input-with-label (not is-checkbox?)
+ :input-label is-text?
+ :radio-label is-radio?
+ :checkbox-label is-checkbox?)
+ :tab-index "0"
+ :for (name input-name)} label
+ (when is-checkbox?
+ [:span {:class (stl/css-case :global/checked value)} i/status-tick-refactor])
+ [:> :input props]]
- (some? children)
- [:label {:for (name input-name)} children])
+ (some? children)
+ [:label {:for (name input-name)}
- (when help-icon'
- [:div.help-icon
- {:style {:cursor "pointer"}
- :on-click (when (= "password" input-type)
- swap-text-password)}
- help-icon'])
- (cond
- (and touched? (:message error))
- [:span.error {:id (dm/str "error-" input-name)
- :data-test (clojure.string/join [data-test "-error"])} (tr (:message error))]
+ [:> :input props]
+ children])
- (string? hint)
- [:span.hint hint])]]))
+ (when help-icon'
+ [:span {:class (stl/css :help-icon)
+ :on-click (when (= "password" input-type)
+ swap-text-password)}
+ help-icon'])
+ (cond
+ (and touched? (:message error))
+ [:div {:id (dm/str "error-" input-name)
+ :class (stl/css :error)
+ :data-test (clojure.string/join [data-test "-error"])}
+ (tr (:message error))]
+
+ (string? hint)
+ [:div {:class (stl/css :hint)} hint])]]
+
+
+ [:div
+ {:class klass}
+ [:*
+ [:> :input props]
+ (cond
+ (some? label)
+ [:label {:for (name input-name)} label]
+
+ (some? children)
+ [:label {:for (name input-name)} children])
+
+ (when help-icon'
+ [:div.help-icon
+ {:style {:cursor "pointer"}
+ :on-click (when (= "password" input-type)
+ swap-text-password)}
+ help-icon'])
+ (cond
+ (and touched? (:message error))
+ [:span.error {:id (dm/str "error-" input-name)
+ :data-test (clojure.string/join [data-test "-error"])} (tr (:message error))]
+
+ (string? hint)
+ [:span.hint hint])]])))
(mf/defc textarea
[{:keys [label disabled form hint trim] :as props}]
@@ -195,7 +246,8 @@
(mf/defc select
[{:keys [options disabled label form default data-test] :as props
:or {default ""}}]
- (let [input-name (get props :name)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ input-name (get props :name)
form (or form (mf/use-ctx form-ctx))
value (or (get-in @form [:data input-name]) default)
cvalue (d/seek #(= value (:value %)) options)
@@ -214,31 +266,57 @@
(fn [_]
(reset! focus? false))]
- [:div.custom-select
- [:select {:value value
- :on-change on-change
- :on-focus on-focus
- :on-blur on-blur
- :disabled disabled
- :data-test data-test}
- (for [item options]
- [:> :option (clj->js (cond-> {:key (:value item) :value (:value item)}
- (:disabled item) (assoc :disabled "disabled")
- (:hidden item) (assoc :style {:display "none"})))
- (:label item)])]
+ (if new-css-system
+ [:div {:class (stl/css :custom-select)}
+ [:select {:value value
+ :on-change on-change
+ :on-focus on-focus
+ :on-blur on-blur
+ :disabled disabled
+ :data-test data-test}
+ (for [item options]
+ [:> :option (clj->js (cond-> {:key (:value item) :value (:value item)}
+ (:disabled item) (assoc :disabled "disabled")
+ (:hidden item) (assoc :style {:display "none"})))
+ (:label item)])]
- [:div.input-container {:class (dom/classnames :disabled disabled :focus @focus?)}
- [:div.main-content
- [:label label]
- [:span.value (:label cvalue "")]]
+ [:div {:class (stl/css-case :input-container true
+ :disabled disabled
+ :focus @focus?)}
+ [:div {:class (stl/css :main-content)}
+ [:label {:class (stl/css :label)} label]
+ [:span {:class (stl/css :value)} (:label cvalue "")]]
- [:div.icon
- i/arrow-slide]]]))
+ [:div {:class (stl/css :icon)}
+ i/arrow-refactor]]]
+
+
+ [:div.custom-select
+ [:select {:value value
+ :on-change on-change
+ :on-focus on-focus
+ :on-blur on-blur
+ :disabled disabled
+ :data-test data-test}
+ (for [item options]
+ [:> :option (clj->js (cond-> {:key (:value item) :value (:value item)}
+ (:disabled item) (assoc :disabled "disabled")
+ (:hidden item) (assoc :style {:display "none"})))
+ (:label item)])]
+
+ [:div.input-container {:class (dom/classnames :disabled disabled :focus @focus?)}
+ [:div.main-content
+ [:label label]
+ [:span.value (:label cvalue "")]]
+
+ [:div.icon
+ i/arrow-slide]]])))
(mf/defc radio-buttons
{::mf/wrap-props false}
[props]
- (let [form (or (unchecked-get props "form")
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ form (or (unchecked-get props "form")
(mf/use-ctx form-ctx))
name (unchecked-get props "name")
@@ -261,28 +339,56 @@
(when (fn? on-change)
(on-change name value)))))]
+ (if new-css-system
+ [:div {:class (stl/css :custom-radio)}
+ (for [{:keys [image value label]} options]
+ (let [image? (some? image)
+ value' (encode-fn value)
+ checked? (= value current-value)
+ key (str/ffmt "%-%" name value')]
+ [:label {:for key
+ :style {:background-image (when image? (str/ffmt "url(%)" image))}
+ :class (stl/css-case :radio-label true
+ :global/checked checked?
+ :with-image image?)}
+ [:input {:on-change on-change'
+ :type "radio"
+ :class (stl/css :radio-input)
+ :id key
+ :name name
+ :value value'
+ :checked checked?}]
+ (when (not image?)
+ [:span {:class (stl/css-case :radio-icon true
+ :global/checked checked?)}
+ (when checked? [:span {:class (stl/css :radio-dot)}])])
- [:div.custom-radio
- (for [{:keys [image value label]} options]
- (let [image? (some? image)
- value' (encode-fn value)
- key (str/ffmt "%-%" name value')]
- [:div.input-radio {:key key :class (when image? "with-image")}
- [:input {:on-change on-change'
- :type "radio"
- :id key
- :name name
- :value value'
- :checked (= value current-value)}]
- [:label {:for key
- :style {:background-image (when image? (str/ffmt "url(%)" image))}
- :class (when image? "with-image")}
- label]]))]))
+ label]))]
+
+
+
+ [:div.custom-radio
+ (for [{:keys [image value label]} options]
+ (let [image? (some? image)
+ value' (encode-fn value)
+ key (str/ffmt "%-%" name value')]
+ [:div.input-radio {:key key :class (when image? "with-image")}
+ [:input {:on-change on-change'
+ :type "radio"
+ :id key
+ :name name
+ :value value'
+ :checked (= value current-value)}]
+ [:label {:for key
+ :style {:background-image (when image? (str/ffmt "url(%)" image))}
+ :class (when image? "with-image")}
+ label]]))])))
(mf/defc submit-button*
{::mf/wrap-props false}
[props]
- (let [form (or (unchecked-get props "form")
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ form (or (unchecked-get props "form")
(mf/use-ctx form-ctx))
label (unchecked-get props "label")
@@ -296,6 +402,7 @@
(true? (unchecked-get props "disabled")))
klass (dm/str class " " (if disabled? "btn-disabled" ""))
+ new-klass (if disabled? (stl/css :btn-disabled) class)
on-key-down
(mf/use-fn
@@ -310,7 +417,7 @@
(obj/set! "onKeyDown" on-key-down)
(obj/set! "name" name)
(obj/set! "label" mf/undefined)
- (obj/set! "className" klass)
+ (obj/set! "className" (if new-css-system new-klass klass))
(obj/set! "type" "submit"))]
[:> "button" props
@@ -338,7 +445,8 @@
(mf/defc multi-input
[{:keys [form label class name trim valid-item-fn caution-item-fn on-submit] :as props}]
- (let [form (or form (mf/use-ctx form-ctx))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ form (or form (mf/use-ctx form-ctx))
input-name (get props :name)
touched? (get-in @form [:touched input-name])
error (get-in @form [:errors input-name])
@@ -360,10 +468,24 @@
:custom-multi-input true
:custom-input true))
+
+ new-css-klass (str (get props :class) " "
+ (stl/css-case
+ :focus @focus?
+ :valid (and touched? (not error))
+ :invalid (and touched? error)
+ :empty empty?
+ :custom-multi-input true))
+
in-klass (str class " "
(dom/classnames
:no-padding (pos? (count @items))))
+ new-css-in-klass (str class " "
+ (stl/css-case
+ :inside-input true
+ :no-padding (pos? (count @items))))
+
on-focus
(mf/use-fn #(reset! focus? true))
@@ -430,29 +552,59 @@
values (filterv #(:valid %) values)]
(update-form! values)))
- [:div {:class klass}
- [:input {:id (name input-name)
- :class in-klass
- :type "text"
- :auto-focus true
- :on-focus on-focus
- :on-blur on-blur
- :on-key-down on-key-down
- :value @value
- :on-change on-change
- :placeholder (when empty? label)}]
- [:label {:for (name input-name)} label]
+ (if new-css-system
+ [:div {:class new-css-klass}
+ [:input {:id (name input-name)
+ :class new-css-in-klass
+ :type "text"
+ :auto-focus true
+ :on-focus on-focus
+ :on-blur on-blur
+ :on-key-down on-key-down
+ :value @value
+ :on-change on-change
+ :placeholder (when empty? label)}]
+ [:label {:for (name input-name)} label]
- (when-let [items (seq @items)]
- [:div.selected-items
- (for [item items]
- [:div.selected-item {:key (:text item)
- :tab-index "0"
- :on-key-down (partial manage-key-down item)}
- [:span.around {:class (dom/classnames "invalid" (not (:valid item))
- "caution" (:caution item))}
- [:span.text (:text item)]
- [:span.icon {:on-click #(remove-item! item)} i/cross]]])])]))
+ (when-let [items (seq @items)]
+ [:div {:class (stl/css :selected-items)}
+ (for [item items]
+ [:div {:class (stl/css :selected-item)
+ :key (:text item)
+ :tab-index "0"
+ :on-key-down (partial manage-key-down item)}
+ [:span {:class (stl/css-case :around true
+ :invalid (not (:valid item))
+ :caution (:caution item))}
+ [:span {:class (stl/css :text)} (:text item)]
+ [:button {:class (stl/css :icon)
+ :on-click #(remove-item! item)} i/close-refactor]]])])]
+
+
+
+ [:div {:class klass}
+ [:input {:id (name input-name)
+ :class in-klass
+ :type "text"
+ :auto-focus true
+ :on-focus on-focus
+ :on-blur on-blur
+ :on-key-down on-key-down
+ :value @value
+ :on-change on-change
+ :placeholder (when empty? label)}]
+ [:label {:for (name input-name)} label]
+
+ (when-let [items (seq @items)]
+ [:div.selected-items
+ (for [item items]
+ [:div.selected-item {:key (:text item)
+ :tab-index "0"
+ :on-key-down (partial manage-key-down item)}
+ [:span.around {:class (dom/classnames "invalid" (not (:valid item))
+ "caution" (:caution item))}
+ [:span.text (:text item)]
+ [:span.icon {:on-click #(remove-item! item)} i/cross]]])])])))
;; --- Validators
diff --git a/frontend/src/app/main/ui/components/forms.scss b/frontend/src/app/main/ui/components/forms.scss
new file mode 100644
index 000000000..707b1fc63
--- /dev/null
+++ b/frontend/src/app/main/ui/components/forms.scss
@@ -0,0 +1,336 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+// INPUT
+.input-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: $s-6;
+ align-items: center;
+ .input-with-label {
+ @include flexColumn;
+ gap: $s-8;
+ @include titleTipography;
+ justify-content: flex-start;
+ align-items: flex-start;
+ height: 100%;
+ width: 100%;
+ padding: 0;
+ cursor: pointer;
+ color: var(--modal-title-foreground-color);
+ text-transform: none;
+ input {
+ @extend .input-element;
+ color: var(--input-foreground-color-active);
+ width: calc(100% - $s-1);
+ margin-top: 0;
+ }
+ // Input autofill
+ input:-webkit-autofill,
+ input:-webkit-autofill:hover,
+ input:-webkit-autofill:focus,
+ input:-webkit-autofill:active {
+ -webkit-text-fill-color: var(--input-foreground-color-active) !important;
+ -webkit-box-shadow: 0 0 0 28px var(--input-background-color) inset !important;
+ border: $s-1 solid var(--input-background-color);
+ }
+ &:focus {
+ outline: none;
+ border: $s-1 solid var(--input-border-color-focus);
+ border-radius: $br-8;
+ }
+ }
+ &:global(.invalid) {
+ input {
+ border: $s-1 solid var(--input-border-color-error);
+ @extend .disabled-input;
+ }
+ }
+}
+
+.help-icon {
+ cursor: pointer;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--input-details-color);
+ }
+}
+.error {
+ color: var(--input-border-color-error);
+}
+
+.hint {
+ @include titleTipography;
+ width: 99%;
+}
+
+.checkbox {
+ @extend .input-checkbox;
+ .checkbox-label {
+ @include titleTipography;
+ display: flex;
+ align-items: center;
+ flex-direction: row-reverse;
+ gap: $s-6;
+ min-height: $s-32;
+ cursor: pointer;
+ span {
+ @extend .checkbox-icon;
+ }
+ input {
+ display: none !important;
+ }
+ &:hover {
+ span {
+ border-color: var(--input-checkbox-border-color-hover);
+ }
+ }
+ }
+}
+
+// SELECT
+.custom-select {
+ @extend .select-wrapper;
+ height: $s-32;
+ .input-container {
+ @include flexRow;
+ height: $s-32;
+ width: 100%;
+ border-radius: $br-8;
+ border: $s-1 solid var(--input-background-color);
+ color: var(--input-foreground-color-active);
+ background-color: var(--input-background-color);
+ .main-content {
+ @include flexColumn;
+ @include titleTipography;
+ position: relative;
+ justify-content: center;
+ flex-grow: 1;
+ height: 100%;
+ padding: $s-8;
+
+ .label {
+ color: var(--input-foreground-color);
+ }
+ .value {
+ width: 100%;
+ padding: 0px;
+ margin: 0px;
+ border: 0px;
+ color: var(--input-foreground-color-active);
+ }
+ }
+ .icon {
+ @include flexCenter;
+ height: $s-32;
+ width: $s-24;
+ pointer-events: none;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ transform: rotate(90deg);
+ }
+ }
+
+ &.disabled {
+ background-color: var(--input-background-color-disabled);
+ border: $s-1 solid var(--input-border-color-disabled);
+ color: var(--input-foreground-color-disabled);
+ }
+ &.focus {
+ outline: none;
+ color: var(--input-foreground-color-active);
+ background-color: var(--input-background-color-active);
+ border: $s-1 solid var(--input-border-color-active);
+ }
+ }
+
+ select {
+ @extend .menu-dropdown;
+ @include titleTipography;
+ box-sizing: border-box;
+ position: absolute;
+ top: 0;
+ left: 0;
+ min-height: $s-32;
+ height: auto;
+ width: calc(100% - 1px);
+ padding: 0 $s-12;
+ margin: 0;
+ border: none;
+ opacity: 0;
+ z-index: $z-index-10;
+ background-color: transparent;
+ cursor: pointer;
+ option {
+ @include titleTipography;
+ color: var(--title-foreground-color-hover);
+ background-color: var(--menu-background-color);
+ appearance: none;
+ height: $s-32;
+ }
+ }
+}
+
+// SUBMIT-BUTTON
+.btn-disabled {
+ @extend .button-disabled;
+ height: $s-32;
+ padding: $s-8 $s-24;
+ border-radius: $br-8;
+}
+
+// MULTI INPUT
+
+.custom-multi-input {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ min-height: $s-40;
+ max-height: $s-180;
+ width: 100%;
+ overflow-y: hidden;
+ .inside-input {
+ @include removeInputStyle;
+ @include titleTipography;
+ @include textEllipsis;
+ width: 100%;
+ max-width: calc(100% - $s-1);
+ min-height: $s-32;
+ padding-top: 0;
+ height: $s-32;
+ padding: $s-8;
+ margin: 0;
+ border-radius: $br-8;
+ background-color: var(--input-background-color);
+ border: $s-1 solid var(--input-background-color);
+ color: var(--input-foreground-color-active);
+ &:focus {
+ outline: none;
+ border: $s-1 solid var(--input-border-color-focus);
+ }
+ }
+ label {
+ display: none;
+ }
+ .selected-items {
+ display: flex;
+ flex-wrap: wrap;
+ gap: $s-4;
+ max-height: $s-136;
+ padding: $s-4 0;
+ overflow-y: scroll;
+ .selected-item {
+ .around {
+ @include flexRow;
+ height: $s-24;
+ width: fit-content;
+ padding-left: $s-6;
+ border-radius: $br-6;
+ background-color: var(--pill-background-color);
+ border: $s-1 solid var(--pill-background-color);
+ box-sizing: border-box;
+ .text {
+ @include titleTipography;
+ padding-right: $s-8;
+ color: var(--pill-foreground-color);
+ }
+
+ .icon {
+ @include flexCenter;
+ @include buttonStyle;
+ height: $s-32;
+ width: $s-24;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+ }
+ &.invalid {
+ background-color: var(--status-error-background-color);
+ .text {
+ color: var(--alert-foreground-color-error);
+ }
+ .icon svg {
+ stroke: var(--alert-foreground-color-error);
+ }
+ }
+ }
+ }
+ }
+ &.empty {
+ }
+ &.invalid {
+ }
+
+ &.focus {
+ }
+ &.valid {
+ }
+}
+
+// RADIO BUTTONS
+
+.custom-radio {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+}
+
+.radio-label {
+ @include titleTipography;
+ @include flexRow;
+ min-height: $s-32;
+ border-radius: $br-8;
+ padding: $s-0 $s-2;
+ &:focus,
+ &:focus-within {
+ outline: none;
+ border: $s-1 solid var(--input-border-color-active);
+ }
+}
+
+.radio-dot {
+ height: $s-8;
+ width: $s-8;
+ border-radius: $br-circle;
+ background-color: var(--color-background-tertiary);
+}
+
+.radio-input {
+ width: 0;
+ margin: 0;
+}
+
+.radio-icon {
+ @extend .checkbox-icon;
+ border-radius: $br-circle;
+}
+
+.radio-label.with-image {
+ display: flex;
+ justify-content: center;
+ height: $s-120;
+ width: $s-140;
+ padding: $s-64 $s-4 0 $s-4;
+ margin-top: $s-16;
+ margin-right: 0;
+ border-radius: $br-8;
+ border: 1px solid var(--color-background-tertiary);
+ background-size: 50px;
+ background-repeat: no-repeat;
+ background-position: center 0.75rem;
+ cursor: pointer;
+ &:global(.checked) {
+ border: 1px solid var(--color-accent-primary);
+ }
+ &:focus,
+ &:focus-within {
+ outline: none;
+ border: $s-1 solid var(--input-border-color-active);
+ }
+}
diff --git a/frontend/src/app/main/ui/components/tab_container.scss b/frontend/src/app/main/ui/components/tab_container.scss
index f30d9fea0..06ac807eb 100644
--- a/frontend/src/app/main/ui/components/tab_container.scss
+++ b/frontend/src/app/main/ui/components/tab_container.scss
@@ -33,7 +33,7 @@
background: var(--color-background-secondary);
padding: $s-2;
cursor: pointer;
- font-size: $fs12;
+ font-size: $fs-12;
.tab-container-tab-wrapper {
@include flexCenter;
flex-direction: row;
diff --git a/frontend/src/app/main/ui/confirm.cljs b/frontend/src/app/main/ui/confirm.cljs
index be4d4dc56..d17cfaee9 100644
--- a/frontend/src/app/main/ui/confirm.cljs
+++ b/frontend/src/app/main/ui/confirm.cljs
@@ -5,9 +5,11 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.confirm
+ (:require-macros [app.main.style :as stl])
(: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]]
@@ -29,7 +31,8 @@
cancel-label
accept-label
accept-style] :as props}]
- (let [locale (mf/deref i18n/locale)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ locale (mf/deref i18n/locale)
on-accept (or on-accept identity)
on-cancel (or on-cancel identity)
@@ -63,42 +66,88 @@
(->> (events/listen js/document EventType.KEYDOWN on-keydown)
(partial events/unlistenByKey))))
- [: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)]])]])]
+ (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.modal-footer
- [:div.action-buttons
- (when-not (= cancel-label :omit)
- [:input.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)]])]])]
- [: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)}
+ (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))
+ :type "button"
+ :value accept-label
+ :on-click accept-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}]]]]])))
diff --git a/frontend/src/app/main/ui/confirm.scss b/frontend/src/app/main/ui/confirm.scss
new file mode 100644
index 000000000..84b9b7ae6
--- /dev/null
+++ b/frontend/src/app/main/ui/confirm.scss
@@ -0,0 +1,70 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+ &.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-msg,
+ .modal-scd-msg,
+ .modal-subtitle {
+ @include titleTipography;
+ }
+ .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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/dashboard/change_owner.cljs b/frontend/src/app/main/ui/dashboard/change_owner.cljs
index 607f115e1..bb8eb1ea7 100644
--- a/frontend/src/app/main/ui/dashboard/change_owner.cljs
+++ b/frontend/src/app/main/ui/dashboard/change_owner.cljs
@@ -5,15 +5,17 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.dashboard.change-owner
+ (:require-macros [app.main.style :as stl])
(:require
- [app.common.spec :as us]
+ [app.common.spec :as us]
[app.main.data.modal :as modal]
[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]
+ [cljs.spec.alpha :as s]
[rumext.v2 :as mf]))
(s/def ::member-id ::us/uuid)
@@ -24,7 +26,8 @@
{::mf/register modal/components
::mf/register-as :leave-and-reassign}
[{:keys [profile team accept]}]
- (let [form (fm/use-form :spec ::leave-modal-form :initial {})
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ form (fm/use-form :spec ::leave-modal-form :initial {})
members-map (mf/deref refs/dashboard-team-members)
members (vals members-map)
@@ -39,34 +42,71 @@
(let [member-id (get-in @form [:clean-data :member-id])]
(accept member-id)))]
- [: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]]
+ (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.modal-content.generic-form
- [:p (tr "modals.leave-and-reassign.hint1" (:name team))]
+ [:div {:class (stl/css :modal-content)}
+ [:p {:class (stl/css :modal-msg)}
+ (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}]]])]
+ (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.modal-footer
- [:div.action-buttons
- [:input.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 (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}]]]]]
+
+
+ [: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}]]]]])))
diff --git a/frontend/src/app/main/ui/dashboard/change_owner.scss b/frontend/src/app/main/ui/dashboard/change_owner.scss
new file mode 100644
index 000000000..799d566c7
--- /dev/null
+++ b/frontend/src/app/main/ui/dashboard/change_owner.scss
@@ -0,0 +1,46 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/dashboard/export.cljs b/frontend/src/app/main/ui/dashboard/export.cljs
index 2f7335d5f..b8ee87519 100644
--- a/frontend/src/app/main/ui/dashboard/export.cljs
+++ b/frontend/src/app/main/ui/dashboard/export.cljs
@@ -5,12 +5,14 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.dashboard.export
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.data.modal :as modal]
[app.main.features :as features]
[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]
@@ -23,18 +25,36 @@
(mf/defc export-entry
{::mf/wrap-props false}
[{:keys [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)]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
- [:div.file-name-label (:name 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-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)]]])))
(defn- mark-file-error
[files file-id]
@@ -60,7 +80,8 @@
::mf/register-as :export
::mf/wrap-props false}
[{:keys [team-id files has-libraries? binary?]}]
- (let [components-v2 (features/use-feature "components/v2")
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ components-v2 (features/use-feature :components-v2)
state* (mf/use-state
#(let [files (mapv (fn [file] (assoc file :loading? true)) files)]
{:status :prepare
@@ -120,66 +141,136 @@
(when-not has-libraries?
(start-export)))
- [:div.modal-overlay
- [:div.modal-container.export-dialog
- [:div.modal-header
- [:div.modal-header-title
- [:h2 (tr "dashboard.export.title")]]
+ (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.modal-close-button
- {:on-click on-cancel} i/close]]
+ (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.modal-content
- [:p.explain (tr "dashboard.export.explain")]
- [:p.detail (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.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"}]]])]
+ [: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.modal-footer
- [:div.action-buttons
- [:input.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
- {:class "primary"
- :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.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.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}]]]])]]
+
+
+ [: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}]]]])]])))
diff --git a/frontend/src/app/main/ui/dashboard/export.scss b/frontend/src/app/main/ui/dashboard/export.scss
new file mode 100644
index 000000000..47a4888bd
--- /dev/null
+++ b/frontend/src/app/main/ui/dashboard/export.scss
@@ -0,0 +1,115 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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-content {
+ @include titleTipography;
+ margin-bottom: $s-24;
+ .modal-msg,
+ .modal-scd-msg,
+ .modal-subtitle {
+ @include titleTipography;
+ }
+ .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-footer {
+ .action-buttons {
+ @extend .modal-action-btns;
+ .cancel-button {
+ @extend .modal-cancel-btn;
+ }
+ .accept-btn {
+ @extend .modal-accept-btn;
+ &.danger {
+ @extend .modal-danger-btn;
+ }
+ }
+ }
+ }
+ }
+}
+
+.file-entry {
+ .file-name {
+ @include flexRow;
+ .file-icon {
+ @include flexCenter;
+ height: $s-16;
+ width: $s-16;
+
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--input-foreground);
+ }
+ }
+ .file-name-label {
+ @include titleTipography;
+ }
+ }
+ &.loading {
+ .file-name {
+ color: var(--pending-color);
+ .file-icon svg:global(#loader-pencil) {
+ color: var(--pending-color);
+ stroke: var(--pending-color);
+ fill: var(--pending-color);
+ }
+ }
+ }
+ &.error {
+ .file-name {
+ color: var(--error-color);
+ .file-icon svg {
+ stroke: var(--error-color);
+ }
+ }
+ }
+
+ &.success {
+ .file-name {
+ color: var(--ok-color);
+ .file-icon svg {
+ stroke: var(--ok-color);
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/dashboard/import.cljs b/frontend/src/app/main/ui/dashboard/import.cljs
index 4edb59bf6..e97686704 100644
--- a/frontend/src/app/main/ui/dashboard/import.cljs
+++ b/frontend/src/app/main/ui/dashboard/import.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.dashboard.import
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -16,6 +17,7 @@
[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]
@@ -149,7 +151,8 @@
(mf/defc import-entry
[{:keys [state file editing? can-be-deleted?]}]
- (let [loading? (or (= :analyzing (:status file))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ loading? (or (= :analyzing (:status file))
(= :importing (:status file)))
analyze-error? (= :analyze-error (:status file))
import-finish? (= :import-finish (:status file))
@@ -187,32 +190,89 @@
(fn []
(swap! state update :files remove-file (:file-id file))))]
- [: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?)))}
+ (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.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)]
+ [: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.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.file-name-label (:name file) (when is-shared? i/library)])
+ [: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")]
+
+ 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)])
+
+ [: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))
@@ -220,31 +280,32 @@
(when can-be-deleted?
[:button {:on-click handle-remove-entry} i/trash])]]
- (cond
- analyze-error?
- [:div.error-message
- (tr "dashboard.import.analyze-error")]
+ (cond
+ analyze-error?
+ [:div.error-message
+ (tr "dashboard.import.analyze-error")]
- import-error?
- [:div.error-message
- (tr "dashboard.import.import-error")]
+ import-error?
+ [:div.error-message
+ (tr "dashboard.import.import-error")]
- (and (not import-finish?) (some? progress))
- [:div.progress-message (parse-progress-message progress)])
+ (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.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)])))]])))
(mf/defc import-dialog
{::mf/register modal/components
::mf/register-as :import}
[{:keys [project-id files template on-finish-import]}]
- (let [state (mf/use-state
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ state (mf/use-state
{:status :analyzing
:editing nil
:importing-templates 0
@@ -364,61 +425,122 @@
#(doseq [file files]
(wapi/revoke-uri (:uri file)))))
- [:div.modal-overlay
- [:div.modal-container.import-dialog
- [:div.modal-header
- [:div.modal-header-title
- [:h2 (tr "dashboard.import")]]
+ (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.modal-close-button
- {:on-click handle-cancel} i/close]]
+ [:button {:class (stl/css :modal-close-btn)
+ :on-click handle-cancel} i/close-refactor]]
- [: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 {:class (stl/css :modal-content)}
- [:div.feedback-banner
- [:div.icon i/checkbox-checked]
- [:div.message (tr "dashboard.import.import-message" (i18n/c (if (some? template) 1 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)]]
- (for [file files]
- (let [editing? (and (some? (:file-id file))
- (= (:file-id file) (:editing @state)))]
+ [: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)
[:& import-entry {:state state
- :key (dm/str (:uri file))
- :file file
- :editing? editing?
- :can-be-deleted? (> (count files) 1)}]))
+ :file (assoc template :status (if (= 1 (:importing-templates @state)) :importing :ready))
+ :editing? false
+ :can-be-deleted? false}])]
- (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 {: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}])
- [: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 {:class (stl/css :accept-btn)
+ :type "button"
+ :value (tr "labels.continue")
+ :disabled (or pending-analysis? (not valid-files?))
+ :on-click handle-continue}])
- (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 {:class (stl/css :accept-btn)
+ :type "button"
+ :value (tr "labels.accept")
+ :disabled (or pending-import? (not valid-files?))
+ :on-click handle-accept}])]]]]
- (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}])]]]]))
+
+
+ [: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}])]]]])))
diff --git a/frontend/src/app/main/ui/dashboard/import.scss b/frontend/src/app/main/ui/dashboard/import.scss
new file mode 100644
index 000000000..a8c8baf22
--- /dev/null
+++ b/frontend/src/app/main/ui/dashboard/import.scss
@@ -0,0 +1,197 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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;
+ .modal-msg,
+ .modal-scd-msg,
+ .modal-subtitle {
+ @include titleTipography;
+ }
+ .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);
+ }
+ }
+ }
+ }
+
+ .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;
+ }
+ }
+ }
+ }
+ }
+}
+
+.file-entry {
+ .file-name {
+ @include flexRow;
+ margin-bottom: $s-8;
+ .file-icon {
+ @include flexCenter;
+ height: $s-24;
+ width: $s-16;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+ &.icon-fill svg {
+ fill: var(--icon-foreground);
+ }
+ }
+ .file-name-edit {
+ @extend .input-element;
+ flex-grow: 1;
+ }
+ .file-name-label {
+ @include titleTipography;
+ flex-grow: 1;
+ }
+ .edit-entry-buttons {
+ @include flexRow;
+ button {
+ @extend .button-tertiary;
+ width: $s-28;
+ height: $s-32;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+ }
+ }
+ }
+ .error-message,
+ .progress-message {
+ height: $s-32;
+ }
+
+ .linked-libraries {
+ .linked-library-tag {
+ @include flexCenter;
+ height: $s-24;
+ width: $s-16;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+ &.error {
+ svg {
+ stroke: var(--error-color);
+ }
+ }
+ }
+ }
+
+ &.loading {
+ .file-name {
+ color: var(--pending-color);
+ .file-icon {
+ :global(#loader-pencil) {
+ color: var(--pending-color);
+ stroke: var(--pending-color);
+ fill: var(--pending-color);
+ }
+ }
+ }
+ }
+ &.warning {
+ .file-name {
+ color: var(--warning-color);
+ .file-icon svg {
+ stroke: var(--warning-color);
+ }
+ .file-icon.icon-fill svg {
+ fill: var(--warning-color);
+ }
+ }
+ }
+ &.success {
+ .file-name {
+ color: var(--ok-color);
+ .file-icon svg {
+ stroke: var(--ok-color);
+ }
+ .file-icon.icon-fill svg {
+ fill: var(--ok-color);
+ }
+ }
+ }
+ &.error {
+ .file-name {
+ color: var(--error-color);
+ .file-icon svg {
+ stroke: var(--error-color);
+ }
+ .file-icon.icon-fill svg {
+ fill: var(--error-color);
+ }
+ }
+ }
+ &.editable {
+ .file-name {
+ color: var(--icon-foreground);
+ .file-icon svg {
+ stroke: var(--icon-foreground);
+ }
+ .file-icon.icon-fill svg {
+ fill: var(--icon-foreground);
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs
index 2d8c298aa..9e854ce2b 100644
--- a/frontend/src/app/main/ui/dashboard/team.cljs
+++ b/frontend/src/app/main/ui/dashboard/team.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.dashboard.team
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -20,6 +21,7 @@
[app.main.ui.components.dropdown :refer [dropdown]]
[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.dashboard.change-owner]
[app.main.ui.dashboard.team-form]
[app.main.ui.icons :as i]
@@ -107,7 +109,8 @@
::mf/register-as :invite-members
::mf/wrap-props false}
[{:keys [team origin]}]
- (let [members-map (mf/deref refs/dashboard-team-members)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ members-map (mf/deref refs/dashboard-team-members)
perms (:permissions team)
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
@@ -153,42 +156,81 @@
(with-meta {::ev/origin origin}))
(dd/fetch-team-invitations))))]
- [:div.modal.dashboard-invite-modal.form-container
- {:class (dom/classnames
- :hero (= origin :hero))}
- [:& fm/form {:on-submit on-submit :form form}
- [:div.title
- [:span.text (tr "modals.invite-team-member.title")]]
- (when-not (= "" @error-text)
- [:div.error
- [:span.icon i/msg-error]
- [:span.text @error-text]])
+ (if new-css-system
+ [:div {:class (stl/css-case :modal-team-container true
+ :hero (= origin :hero))}
+ [:& fm/form {:on-submit on-submit :form form}
+ [:div {:class (stl/css :modal-title)}
+ (tr "modals.invite-team-member.title")]
- (when (some current-data-emails current-members-emails)
- [:div.warning
- [:span.icon i/msg-warning]
- [:span.text (tr "modals.invite-member.repeated-invitation")]])
+ (when-not (= "" @error-text)
+ [:div {:class (stl/css :error-msg)}
+ [:span {:class (stl/css :icon)} i/msg-error]
+ [:span {:class (stl/css :message)} @error-text]])
- [:div.form-row
- [:p.label (tr "onboarding.choice.team-up.roles")]
- [:& fm/select {:name :role :options roles}]]
+ (when (some current-data-emails current-members-emails)
+ [:div {:class (stl/css :warning-msg)}
+ [:span {:class (stl/css :icon)} i/msg-warning]
+ [:span {:class (stl/css :message)} (tr "modals.invite-member.repeated-invitation")]])
- [:div.form-row
- [:& fm/multi-input {:type "email"
- :name :emails
- :auto-focus? true
- :trim true
- :valid-item-fn us/parse-email
- :caution-item-fn current-members-emails
- :label (tr "modals.invite-member.emails")
- :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.action-buttons
- [:> fm/submit-button*
- {:label (tr "modals.invite-member-confirm.accept")
- :disabled (and (boolean (some current-data-emails current-members-emails))
- (empty? (remove current-members-emails current-data-emails)))}]]]]))
+ [: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 current-members-emails
+ :label (tr "modals.invite-member.emails")
+ :on-submit on-submit}]]
+
+ [:div {:class (stl/css :action-buttons)}
+ [:> fm/submit-button*
+ {:label (tr "modals.invite-member-confirm.accept")
+ :disabled (and (boolean (some current-data-emails current-members-emails))
+ (empty? (remove current-members-emails current-data-emails)))}]]]]
+
+
+ [:div.modal.dashboard-invite-modal.form-container
+ {:class (dom/classnames
+ :hero (= origin :hero))}
+ [:& fm/form {:on-submit on-submit :form form}
+ [:div.title
+ [:span.text (tr "modals.invite-team-member.title")]]
+
+ (when-not (= "" @error-text)
+ [:div.error
+ [:span.icon i/msg-error]
+ [:span.text @error-text]])
+
+ (when (some current-data-emails current-members-emails)
+ [:div.warning
+ [:span.icon i/msg-warning]
+ [:span.text (tr "modals.invite-member.repeated-invitation")]])
+
+ [:div.form-row
+ [:p.label (tr "onboarding.choice.team-up.roles")]
+ [:& fm/select {:name :role :options roles}]]
+
+ [:div.form-row
+ [:& fm/multi-input {:type "email"
+ :name :emails
+ :auto-focus? true
+ :trim true
+ :valid-item-fn us/parse-email
+ :caution-item-fn current-members-emails
+ :label (tr "modals.invite-member.emails")
+ :on-submit on-submit}]]
+
+ [:div.action-buttons
+ [:> fm/submit-button*
+ {:label (tr "modals.invite-member-confirm.accept")
+ :disabled (and (boolean (some current-data-emails current-members-emails))
+ (empty? (remove current-members-emails current-data-emails)))}]]]])))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MEMBERS SECTION
@@ -710,7 +752,8 @@
::mf/register-as :webhook}
[{:keys [webhook] :as props}]
;; FIXME: this is a workaround because input fields do not support rendering hooks
- (let [initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str))
{:is-active false :mtype "application/json"})))
form (fm/use-form :spec ::webhook-form
:initial initial
@@ -771,54 +814,100 @@
(let [data (:clean-data @form)]
(if (:id data)
(on-update-submit form)
- (on-create-submit form)))))]
+ (on-create-submit form)))))
- [:div.modal-overlay
- [:div.modal-container.webhooks-modal
- [:& fm/form {:form form :on-submit on-submit}
+ on-modal-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-header)}
+ (if webhook
+ [:h2 {:class (stl/css :modal-title)} (tr "modals.edit-webhook.title")]
+ [:h2 {:class (stl/css :modal-title)} (tr "modals.create-webhook.title")])
- [:div.modal-header
- [:div.modal-header-title
- (if webhook
- [:h2 (tr "modals.edit-webhook.title")]
- [:h2 (tr "modals.create-webhook.title")])]
+ [:button {:class (stl/css :modal-close-btn)
+ :on-click on-modal-close} i/close-refactor]]
- [:div.modal-close-button
- {:on-click #(st/emit! (modal/hide))} i/close]]
-
- [:div.modal-content.generic-form
- [:div.fields-container
- [:div.fields-row
- [:& fm/input {:type "text"
- :auto-focus? true
- :form form
- :name :uri
- :label (tr "modals.create-webhook.url.label")
- :placeholder (tr "modals.create-webhook.url.placeholder")}]]
-
- [:div.fields-row
+ [:div {:class (stl/css :modal-content)}
+ [:div {:class (stl/css :fields-row)}
+ [:& fm/input {:type "text"
+ :auto-focus? true
+ :form form
+ :name :uri
+ :label (tr "modals.create-webhook.url.label")
+ :placeholder (tr "modals.create-webhook.url.placeholder")}]]
+ [:div {:class (stl/css :fields-row)}
+ [:div {:class (stl/css :select-title)} (tr "dashboard.webhooks.content-type")]
[:& fm/select {:options valid-webhook-mtypes
- :label (tr "dashboard.webhooks.content-type")
:default "application/json"
- :name :mtype}]]]
- [:div.fields-row
- [:div.input-checkbox.check-primary
- [:& fm/input {:type "checkbox"
- :form form
- :name :is-active
- :label (tr "dashboard.webhooks.active")}]]
- [:div.explain (tr "dashboard.webhooks.active.explain")]]]
+ :name :mtype}]]
+ [:div {:class (stl/css :fields-row)}
+ [:& fm/input {:type "checkbox"
+ :class (stl/css :custom-input-checkbox)
+ :form form
+ :name :is-active
+ :label (tr "dashboard.webhooks.active")}]
+ [:div {:class (stl/css :hint)} (tr "dashboard.webhooks.active.explain")]]]
- [:div.modal-footer
- [:div.action-buttons
- [:input.cancel-button
- {:type "button"
- :value (tr "labels.cancel")
- :on-click #(modal/hide!)}]
- [:> fm/submit-button*
- {:label (if webhook
- (tr "modals.edit-webhook.submit-label")
- (tr "modals.create-webhook.submit-label"))}]]]]]]))
+ [: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 #(modal/hide!)}]
+ [:> fm/submit-button*
+ {:label (if webhook
+ (tr "modals.edit-webhook.submit-label")
+ (tr "modals.create-webhook.submit-label"))}]]]]]]
+
+
+ [:div.modal-overlay
+ [:div.modal-container.webhooks-modal
+ [:& fm/form {:form form :on-submit on-submit}
+
+ [:div.modal-header
+ [:div.modal-header-title
+ (if webhook
+ [:h2 (tr "modals.edit-webhook.title")]
+ [:h2 (tr "modals.create-webhook.title")])]
+
+ [:div.modal-close-button
+ {:on-click #(st/emit! (modal/hide))} i/close]]
+
+ [:div.modal-content.generic-form
+ [:div.fields-container
+ [:div.fields-row
+ [:& fm/input {:type "text"
+ :auto-focus? true
+ :form form
+ :name :uri
+ :label (tr "modals.create-webhook.url.label")
+ :placeholder (tr "modals.create-webhook.url.placeholder")}]]
+
+ [:div.fields-row
+ [:& fm/select {:options valid-webhook-mtypes
+ :label (tr "dashboard.webhooks.content-type")
+ :default "application/json"
+ :name :mtype}]]]
+ [:div.fields-row
+ [:div.input-checkbox.check-primary
+ [:& fm/input {:type "checkbox"
+ :form form
+ :name :is-active
+ :label (tr "dashboard.webhooks.active")}]]
+ [:div.explain (tr "dashboard.webhooks.active.explain")]]]
+
+ [:div.modal-footer
+ [:div.action-buttons
+ [:input.cancel-button
+ {:type "button"
+ :value (tr "labels.cancel")
+ :on-click #(modal/hide!)}]
+ [:> fm/submit-button*
+ {:label (if webhook
+ (tr "modals.edit-webhook.submit-label")
+ (tr "modals.create-webhook.submit-label"))}]]]]]])))
(mf/defc webhooks-hero
diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss
new file mode 100644
index 000000000..b7e254209
--- /dev/null
+++ b/frontend/src/app/main/ui/dashboard/team.scss
@@ -0,0 +1,142 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-team-container {
+ @extend .modal-container-base;
+ @include menuShadow;
+ position: fixed;
+ top: $s-72;
+ right: $s-12;
+ left: unset;
+ width: $s-400;
+ padding: $s-32;
+ background-color: var(--modal-background-color);
+ border: $s-1 solid var(--modal-border-color);
+ &.hero {
+ top: $s-216;
+ right: $s-32;
+ }
+ .modal-title {
+ @include tabTitleTipography;
+ height: $s-32;
+ color: var(--modal-title-foreground-color);
+ }
+ .error-msg {
+ @include flexRow;
+ height: $s-32;
+ border-radius: $br-8;
+ background-color: var(--alert-background-color-error);
+ .icon {
+ @include flexCenter;
+ width: $s-16;
+ height: $s-24;
+ svg {
+ @extend .button-icon;
+ stroke: var(--alert-foreground-color-error);
+ }
+ }
+ .message {
+ @include titleTipography;
+ color: var(--alert-foreground-color-error);
+ }
+ }
+
+ .warning-msg {
+ @include flexRow;
+ height: $s-32;
+ border-radius: $br-8;
+ background-color: var(--alert-background-color-warning);
+ .icon {
+ @include flexCenter;
+ width: $s-16;
+ height: $s-24;
+ svg {
+ @extend .button-icon;
+ stroke: var(--alert-foreground-color-warning);
+ }
+ }
+ .message {
+ @include titleTipography;
+ color: var(--alert-foreground-color-warning);
+ }
+ }
+
+ .role-select {
+ @include flexColumn;
+ .role-title {
+ @include titleTipography;
+ margin: 0;
+ color: var(--modal-title-foreground-color);
+ }
+ }
+ .invitation-row {
+ margin-top: $s-8;
+ margin-bottom: $s-24;
+ }
+
+ .action-buttons {
+ display: flex;
+ justify-content: flex-end;
+ button {
+ @extend .modal-accept-btn;
+ &:disabled {
+ @extend .button-disabled;
+ }
+ }
+ }
+}
+
+// WEBHOOKS
+
+.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;
+
+ .fields-row {
+ @include flexColumn;
+ .select-title {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+ }
+ .custom-input-checkbox {
+ align-items: flex-start;
+ }
+ }
+ }
+
+ .modal-footer {
+ .action-buttons {
+ @extend .modal-action-btns;
+ button {
+ @extend .modal-accept-btn;
+ }
+ .cancel-button {
+ @extend .modal-cancel-btn;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/dashboard/team_form.cljs b/frontend/src/app/main/ui/dashboard/team_form.cljs
index 023cfac48..5333e7225 100644
--- a/frontend/src/app/main/ui/dashboard/team_form.cljs
+++ b/frontend/src/app/main/ui/dashboard/team_form.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.dashboard.team-form
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.spec :as us]
[app.main.data.dashboard :as dd]
@@ -12,6 +13,7 @@
[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]
@@ -68,36 +70,73 @@
(mf/defc team-form-modal {::mf/register modal/components
::mf/register-as :team-form}
[{:keys [team] :as props}]
- (let [initial (mf/use-memo (fn [] (or team {})))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ 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)]
- [:div.modal-overlay
- [:div.modal-container.team-form-modal
- [:& fm/form {:form form :on-submit on-submit}
+ :initial initial)
+ on-close #(st/emit! (modal/hide))]
- [:div.modal-header
- [:div.modal-header-title
- (if team
- [:h2 (tr "labels.rename-team")]
- [:h2 (tr "labels.create-team")])]
+ (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.modal-close-button
- {:on-click #(st/emit! (modal/hide))} i/close]]
+ [: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.modal-content.generic-form
- [:& fm/input {:type "text"
- :auto-focus? true
- :form form
- :name :name
- :label (tr "labels.create-team.placeholder")}]]
+ [:button {:class (stl/css :modal-close-btn)
+ :on-click on-close} i/close-refactor]]
- [: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-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"))}]]]]]])))
diff --git a/frontend/src/app/main/ui/dashboard/team_form.scss b/frontend/src/app/main/ui/dashboard/team_form.scss
new file mode 100644
index 000000000..12f33182f
--- /dev/null
+++ b/frontend/src/app/main/ui/dashboard/team_form.scss
@@ -0,0 +1,65 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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 {
+ margin-bottom: $s-24;
+}
+
+.group-name-input {
+ @extend .input-element-label;
+ label {
+ @include flexColumn;
+ @include titleTipography;
+ align-items: flex-start;
+ width: 100%;
+ border: none;
+ background-color: transparent;
+ height: 100%;
+
+ input {
+ @include titleTipography;
+ margin-top: $s-8;
+ }
+ }
+}
+
+.action-buttons {
+ @extend .modal-action-btns;
+}
+
+.cancel-button {
+ @extend .modal-cancel-btn;
+}
+.accept-btn {
+ @extend .modal-accept-btn;
+ &.danger {
+ @extend .modal-danger-btn;
+ }
+}
diff --git a/frontend/src/app/main/ui/debug/components_preview.scss b/frontend/src/app/main/ui/debug/components_preview.scss
index a78e2e2dc..dfe86ab61 100644
--- a/frontend/src/app/main/ui/debug/components_preview.scss
+++ b/frontend/src/app/main/ui/debug/components_preview.scss
@@ -91,7 +91,7 @@
border-radius: $s-8;
h3 {
@include titleTipography;
- font-size: $fs-25;
+ font-size: $fs-24;
width: 100%;
}
.component {
diff --git a/frontend/src/app/main/ui/delete_shared.cljs b/frontend/src/app/main/ui/delete_shared.cljs
index 464a8b2e3..1fb568b96 100644
--- a/frontend/src/app/main/ui/delete_shared.cljs
+++ b/frontend/src/app/main/ui/delete_shared.cljs
@@ -5,11 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.delete-shared
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[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]]
@@ -25,7 +27,8 @@
::mf/register-as :delete-shared-libraries
::mf/wrap-props false}
[{:keys [ids on-accept on-cancel accept-style origin count-libraries]}]
- (let [references* (mf/use-state {})
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ references* (mf/use-state {})
references (deref references*)
on-accept (or on-accept noop)
@@ -93,45 +96,91 @@
(let [key (events/listen js/document "keydown" on-keydown)]
(partial events/unlistenByKey key))))
- [: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]]
+ (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.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 {: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.modal-footer
- [:div.action-buttons
- (when-not (= cancel-label :omit)
- [:input.cancel-button
- {:type "button"
- :value cancel-label
- :on-click cancel-fn}])
+ [: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.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}]]]]]
+
+
+ [: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}]]]]]
+ )
+
+ ))
diff --git a/frontend/src/app/main/ui/delete_shared.scss b/frontend/src/app/main/ui/delete_shared.scss
new file mode 100644
index 000000000..17c2531a7
--- /dev/null
+++ b/frontend/src/app/main/ui/delete_shared.scss
@@ -0,0 +1,59 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+ &.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-msg,
+ .modal-scd-msg,
+ .modal-subtitle {
+ @include titleTipography;
+ }
+ .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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/export.cljs b/frontend/src/app/main/ui/export.cljs
index 7f164a983..710e5efc5 100644
--- a/frontend/src/app/main/ui/export.cljs
+++ b/frontend/src/app/main/ui/export.cljs
@@ -26,7 +26,8 @@
(mf/defc export-multiple-dialog
[{:keys [exports title cmd no-selection]}]
- (let [lstate (mf/deref refs/export)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ lstate (mf/deref refs/export)
in-progress? (:in-progress lstate)
exports (mf/use-state exports)
@@ -61,91 +62,198 @@
(fn [_]
(swap! exports (fn [exports]
(mapv #(assoc % :enabled (not all-checked?)) exports))))]
- [:div.modal-overlay
- [:div.modal-container.export-multiple-dialog
- {:class (when (empty? all-exports) "empty")}
- [:div.modal-header
- [:div.modal-header-title
- [:h2 title]]
+ (if new-css-system
+ [:div {:class (stl/css :modal-overlay)}
+ [:div.modal-container.export-multiple-dialog
+ {:class (stl/css-case :modal-container true
+ :empty (empty? all-exports))}
- [:div.modal-close-button
- {:on-click cancel-fn} i/close]]
+ [: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.modal-content
- (if (> (count all-exports) 0)
- [:*
- [:div.header
- [:div.field.check {:on-click change-all}
- (cond
- all-checked? [:span.checked i/checkbox-checked]
- all-unchecked? [:span.unchecked i/checkbox-unchecked]
- :else [:span.intermediate i/checkbox-intermediate])]
- [:div.field.title (tr "dashboard.export-multiple.selected"
- (c (count enabled-exports))
- (c (count all-exports)))]]
+ [:*
+ [:div {:class (stl/css :modal-content)}
+ (if (> (count all-exports) 0)
+ [:*
+ [:div {:class (stl/css :selection-header)}
+ [:button {:class (stl/css :selection-btn)
+ :on-click change-all}
+ [:span {:class (stl/css :checkbox-wrapper)}
+ (cond
+ all-checked? [:span {:class (stl/css-case :checkbox-icon2 true
+ :global/checked true)} i/tick-refactor]
+ all-unchecked? [:span {:class (stl/css-case :checkbox-icon2 true
+ :global/uncheked true)}]
+ :else [:span {:class (stl/css-case :checkbox-icon2 true
+ :global/intermediate true)} i/remove-refactor])]]
+ [:div {:class (stl/css :selection-title)} (tr "dashboard.export-multiple.selected"
+ (c (count enabled-exports))
+ (c (count all-exports)))]]
+ [:div {:class (stl/css :selection-wrapper)}
+ [:div {:class (stl/css-case :selection-list true
+ :selection-shadow (> (count all-exports) 8))}
+ (for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
+ (let [{:keys [x y width height]} (:selrect shape)]
+ [:div {:class (stl/css :selection-row)}
+ [:button {:class (stl/css :selection-btn)
+ :on-click #(on-toggle-enabled index)}
+ [:span {:class (stl/css :checkbox-wrapper)}
+ (if (:enabled export)
+ [:span {:class (stl/css-case :checkbox-icon2 true
+ :global/checked true)} i/tick-refactor]
+ [:span {:class (stl/css-case :checkbox-icon2 true
+ :global/uncheked true)}])]
- [:div.body
- (for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
- (let [{:keys [x y width height]} (:selrect shape)]
- [:div.row
- [:div.field.check {:on-click #(on-toggle-enabled index)}
- (if (:enabled export)
- [:span.checked i/checkbox-checked]
- [:span.unchecked i/checkbox-unchecked])]
+ [:div {:class (stl/css :image-wrapper)}
+ (if (some? (:thumbnail shape))
+ [:img {:src (:thumbnail shape)}]
+ [:svg {:view-box (dm/str x " " y " " width " " height)
+ :width 24
+ :height 20
+ :version "1.1"
+ :xmlns "http://www.w3.org/2000/svg"
+ :xmlnsXlink "http://www.w3.org/1999/xlink"
+ ;; Fix Chromium bug about color of html texts
+ ;; https://bugs.chromium.org/p/chromium/issues/detail?id=1244560#c5
+ :style {:-webkit-print-color-adjust :exact}
+ :fill "none"}
- [:div.field.image
- (if (some? (:thumbnail shape))
- [:img {:src (:thumbnail shape)}]
- [:svg {:view-box (dm/str x " " y " " width " " height)
- :width 24
- :height 20
- :version "1.1"
- :xmlns "http://www.w3.org/2000/svg"
- :xmlnsXlink "http://www.w3.org/1999/xlink"
- ;; Fix Chromium bug about color of html texts
- ;; https://bugs.chromium.org/p/chromium/issues/detail?id=1244560#c5
- :style {:-webkit-print-color-adjust :exact}
- :fill "none"}
+ [:& shape-wrapper {:shape shape}]])]
- [:& shape-wrapper {:shape shape}]])]
+ [:div {:class (stl/css :selection-name)} (cond-> (:name shape) suffix (str suffix))]
+ (when (:scale export)
+ [:div {:class (stl/css :selection-scale)}
+ (dm/str (ust/format-precision (* width (:scale export)) 2) "x"
+ (ust/format-precision (* height (:scale export)) 2) "px ")])
- [:div.field.name (cond-> (:name shape) suffix (str suffix))]
- (when (:scale export)
- [:div.field.scale (dm/str (ust/format-precision (* width (:scale export)) 2) "x"
- (ust/format-precision (* height (:scale export)) 2) "px ")])
+ (when (:type export)
+ [:div {:class (stl/css :selection-extension)}
+ (-> export :type d/name str/upper)])]]))]]]
- (when (:type export)
- [:div.field.extension (-> export :type d/name str/upper)])]))]
+ [:& no-selection])]
- [:div.modal-footer
- [:div.action-buttons
- [:input.cancel-button
- {:type "button"
+ (when (> (count all-exports) 0)
+ [: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 cancel-fn}]
- [:input.accept-button.primary
- {:class (dom/classnames
- :btn-disabled (or in-progress? all-unchecked?))
- :disabled (or in-progress? all-unchecked?)
- :type "button"
- :value (if in-progress?
- (tr "workspace.options.exporting-object")
- (tr "labels.export"))
- :on-click (when-not in-progress? accept-fn)}]]]]
+ [:input {:class (stl/css-case :accept-btn true
+ :btn-disabled (or in-progress? all-unchecked?))
+ :disabled (or in-progress? all-unchecked?)
+ :type "button"
+ :value (if in-progress?
+ (tr "workspace.options.exporting-object")
+ (tr "labels.export"))
+ :on-click (when-not in-progress? accept-fn)}]]])]]]
- [:& no-selection])]]]]))
+
+
+ [:div.modal-overlay
+ [:div.modal-container.export-multiple-dialog
+ {:class (when (empty? all-exports) "empty")}
+
+ [:div.modal-header
+ [:div.modal-header-title
+ [:h2 title]]
+
+ [:div.modal-close-button
+ {:on-click cancel-fn} i/close]]
+
+ [:*
+ [:div.modal-content
+ (if (> (count all-exports) 0)
+ [:*
+
+
+ [:div.header
+ [:div.field.check {:on-click change-all}
+ (cond
+ all-checked? [:span.checked i/checkbox-checked]
+ all-unchecked? [:span.unchecked i/checkbox-unchecked]
+ :else [:span.intermediate i/checkbox-intermediate])]
+ [:div.field.title (tr "dashboard.export-multiple.selected"
+ (c (count enabled-exports))
+ (c (count all-exports)))]]
+
+ [:div.body
+ (for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
+ (let [{:keys [x y width height]} (:selrect shape)]
+ [:div.row
+ [:div.field.check {:on-click #(on-toggle-enabled index)}
+ (if (:enabled export)
+ [:span.checked i/checkbox-checked]
+ [:span.unchecked i/checkbox-unchecked])]
+
+ [:div.field.image
+ (if (some? (:thumbnail shape))
+ [:img {:src (:thumbnail shape)}]
+ [:svg {:view-box (dm/str x " " y " " width " " height)
+ :width 24
+ :height 20
+ :version "1.1"
+ :xmlns "http://www.w3.org/2000/svg"
+ :xmlnsXlink "http://www.w3.org/1999/xlink"
+ ;; Fix Chromium bug about color of html texts
+ ;; https://bugs.chromium.org/p/chromium/issues/detail?id=1244560#c5
+ :style {:-webkit-print-color-adjust :exact}
+ :fill "none"}
+
+ [:& shape-wrapper {:shape shape}]])]
+
+ [:div.field.name (cond-> (:name shape) suffix (str suffix))]
+ (when (:scale export)
+ [:div.field.scale (dm/str (ust/format-precision (* width (:scale export)) 2) "x"
+ (ust/format-precision (* height (:scale export)) 2) "px ")])
+
+ (when (:type export)
+ [:div.field.extension (-> export :type d/name str/upper)])]))]
+
+ [:div.modal-footer
+ [:div.action-buttons
+ [:input.cancel-button
+ {:type "button"
+ :value (tr "labels.cancel")
+ :on-click cancel-fn}]
+
+ [:input.accept-button.primary
+ {:class (dom/classnames
+ :btn-disabled (or in-progress? all-unchecked?))
+ :disabled (or in-progress? all-unchecked?)
+ :type "button"
+ :value (if in-progress?
+ (tr "workspace.options.exporting-object")
+ (tr "labels.export"))
+ :on-click (when-not in-progress? accept-fn)}]]]]
+
+ [:& no-selection])]]]])))
(mf/defc shapes-no-selection []
- [:div.no-selection
- [:img {:src "images/export-no-shapes.png" :border "0"}]
- [:p (tr "dashboard.export-shapes.no-elements")]
- [:p (tr "dashboard.export-shapes.how-to")]
- [:p [:a {:target "_blank"
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (if new-css-system
+ [:div {:class (stl/css :no-selection)}
+ [:p {:class (stl/css :modal-msg)}(tr "dashboard.export-shapes.no-elements")]
+ [:p {:class (stl/css :modal-scd-msg)}(tr "dashboard.export-shapes.how-to")]
+ [:a {:target "_blank"
+ :class (stl/css :modal-link)
:href "https://help.penpot.app/user-guide/exporting/ "}
- (tr "dashboard.export-shapes.how-to-link")]]])
+ (tr "dashboard.export-shapes.how-to-link")]]
+
+
+ [:div.no-selection
+ [:img {:src "images/export-no-shapes.png" :border "0"}]
+ [:p (tr "dashboard.export-shapes.no-elements")]
+ [:p (tr "dashboard.export-shapes.how-to")]
+ [:p [:a {:target "_blank"
+ :href "https://help.penpot.app/user-guide/exporting/ "}
+ (tr "dashboard.export-shapes.how-to-link")]]])))
(mf/defc export-shapes-dialog
{::mf/register modal/components
diff --git a/frontend/src/app/main/ui/export.scss b/frontend/src/app/main/ui/export.scss
index e4aa1d2c8..785f42bde 100644
--- a/frontend/src/app/main/ui/export.scss
+++ b/frontend/src/app/main/ui/export.scss
@@ -38,14 +38,14 @@
@include titleTipography;
padding: 0;
margin: 0;
- color: var(--modal-foreground-color);
+ color: var(--modal-title-foreground-color);
padding-left: $s-4;
}
.progress {
@include titleTipography;
padding-left: $s-8;
margin: 0;
- color: var(--modal-foreground-color-secondary);
+ color: var(--modal-text-foreground-color);
}
.retry-btn {
@extend .button-tertiary;
@@ -66,3 +66,159 @@
}
}
}
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+ &.transparent {
+ background-color: transparent;
+ }
+ .modal-container {
+ @extend .modal-container-base;
+ max-height: calc(10 * $s-80);
+ .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,
+ .no-selection {
+ @include titleTipography;
+ margin-bottom: $s-24;
+ .modal-msg,
+ .modal-scd-msg,
+ .modal-hint,
+ .modal-subtitle {
+ @include titleTipography;
+ color: var(--modal-text-foreground-color);
+ }
+ .modal-link {
+ @include titleTipography;
+ text-decoration: none;
+ cursor: pointer;
+ color: var(--modal-link-foreground-color);
+ }
+ .selection-header {
+ @include flexRow;
+ height: $s-32;
+ margin-bottom: $s-4;
+ .selection-btn {
+ @include buttonStyle;
+ @extend .input-checkbox;
+ @include flexCenter;
+ height: $s-24;
+ width: $s-24;
+ padding: 0;
+ margin-left: $s-16;
+ span {
+ @extend .checkbox-icon;
+ }
+ }
+ .selection-title {
+ @include titleTipography;
+ }
+ }
+ .selection-wrapper {
+ position: relative;
+ width: 100%;
+ height: fit-content;
+ }
+ .selection-shadow {
+ width: 100%;
+ height: 100%;
+ &:after {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 50px;
+ background: linear-gradient(to top, rgba(24, 24, 26, 1) 0%, rgba(24, 24, 26, 0) 100%);
+ content: "";
+ pointer-events: none;
+ }
+ }
+ .selection-list {
+ @include flexColumn;
+ max-height: $s-400;
+ overflow-y: auto;
+ padding-bottom: $s-12;
+ .selection-row {
+ @include flexRow;
+ background-color: var(--entry-background-color);
+ min-height: $s-40;
+ border-radius: $br-8;
+ .selection-btn {
+ @include buttonStyle;
+ @include flexRow;
+ width: 100%;
+ height: 10%;
+ gap: $s-8;
+ padding: 0 $s-16;
+ .checkbox-wrapper {
+ @extend .input-checkbox;
+ @include flexCenter;
+ height: $s-24;
+ width: $s-24;
+ padding: 0;
+ .checkbox-icon2 {
+ @extend .checkbox-icon;
+ }
+ }
+ .selection-name {
+ @include titleTipography;
+ @include textEllipsis;
+ flex-grow: 1;
+ color: var(--modal-text-foreground-color);
+ text-align: start;
+ }
+ .selection-scale {
+ @include titleTipography;
+ @include textEllipsis;
+ min-width: $s-108;
+ padding: $s-12;
+ color: var(--modal-text-foreground-color);
+ }
+ .selection-extension {
+ @include titleTipography;
+ @include textEllipsis;
+ min-width: $s-72;
+ padding: $s-12;
+ color: var(--modal-text-foreground-color);
+ }
+ }
+ .image-wrapper {
+ @include flexCenter;
+ height: 100%;
+ min-height: $s-32;
+ min-width: $s-32;
+ background-color: var(--white);
+ border-radius: $br-6;
+ margin: auto 0;
+ img,
+ svg {
+ object-fit: contain;
+ }
+ }
+ }
+ }
+ }
+ .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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs
index b24abe32d..20071dfd5 100644
--- a/frontend/src/app/main/ui/icons.cljs
+++ b/frontend/src/app/main/ui/icons.cljs
@@ -391,6 +391,10 @@
(def masked-refactor (icon-xref :masked-refactor))
(def menu-refactor (icon-xref :menu-refactor))
(def merge-nodes-refactor (icon-xref :merge-nodes-refactor))
+(def msg-error-refactor (icon-xref :msg-error-refactor))
+(def msg-neutral-refactor (icon-xref :msg-neutral-refactor))
+(def msg-success-refactor (icon-xref :msg-success-refactor))
+(def msg-warning-refactor (icon-xref :msg-warning-refactor))
(def move-refactor (icon-xref :move-refactor))
(def open-link-refactor (icon-xref :open-link-refactor))
(def open-refactor (icon-xref :open-refactor))
@@ -448,9 +452,11 @@
(def text-underlined-refactor (icon-xref :text-underlined-refactor))
(def text-uppercase-refactor (icon-xref :text-uppercase-refactor))
(def tick-refactor (icon-xref :tick-refactor))
+(def tree-refactor (icon-xref :tree-refactor))
(def to-corner-refactor (icon-xref :to-corner-refactor))
(def to-curve-refactor (icon-xref :to-curve-refactor))
(def unlock-refactor (icon-xref :unlock-refactor))
+(def user-refactor (icon-xref :user-refactor))
(def vertical-align-items-center-refactor (icon-xref :vertical-align-items-center-refactor))
(def vertical-align-items-end-refactor (icon-xref :vertical-align-items-end-refactor))
(def vertical-align-items-start-refactor (icon-xref :vertical-align-items-start-refactor))
diff --git a/frontend/src/app/main/ui/messages.cljs b/frontend/src/app/main/ui/messages.cljs
index 36a9e94be..f04919fc6 100644
--- a/frontend/src/app/main/ui/messages.cljs
+++ b/frontend/src/app/main/ui/messages.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.messages
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -13,49 +14,96 @@
[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}]
- [: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)}]])]
+ (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)]
- (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])]])
+ [: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])]])))
(mf/defc notifications
[]
diff --git a/frontend/src/app/main/ui/messages.scss b/frontend/src/app/main/ui/messages.scss
new file mode 100644
index 000000000..1479f2f14
--- /dev/null
+++ b/frontend/src/app/main/ui/messages.scss
@@ -0,0 +1,130 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.banner {
+ --bg-color: var(--alert-background-color-error);
+ --fg-color: var(--alert-foreground-color-error);
+ position: relative;
+ display: flex;
+ align-items: center;
+ border-radius: $br-8;
+ background-color: var(--bg-color);
+ color: var(--fg-color);
+}
+.warning {
+ --bg-color: var(--alert-background-color-warning);
+ --fg-color: var(--alert-foreground-color-warning);
+}
+
+.success {
+ --bg-color: var(--alert-background-color-ok);
+ --fg-color: var(--alert-foreground-color-ok);
+}
+
+.info {
+ --bg-color: var(--alert-background-color-neutral);
+ --fg-color: var(--alert-foreground-color-neutral-active);
+}
+.banner.info .icon {
+ --fg-color: var(--alert-foreground-color-neutral);
+}
+.banner.info:hover .icon {
+ --fg-color: var(--alert-foreground-color-neutral);
+}
+
+.wrapper {
+ display: grid;
+ grid-template-columns: $s-16 1fr $s-40;
+ padding: $s-8 $s-8 $s-8 $s-16;
+ gap: $s-8;
+ height: 100%;
+ width: 100%;
+}
+
+.icon {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon;
+ stroke: var(--fg-color);
+ }
+}
+
+.fixed {
+ @include alertShadow;
+ position: fixed;
+ top: $s-16;
+ right: $s-16;
+ display: flex;
+ align-items: center;
+ height: $s-48;
+ min-width: $s-500;
+ max-width: calc(10 * $s-100);
+ padding-left: $s-16;
+ z-index: $z-index-alert;
+}
+
+.floating {
+ @include alertShadow;
+ position: absolute;
+ min-height: $s-32;
+ top: $s-72;
+ left: 0;
+ right: 0;
+ width: $s-640;
+ margin-left: auto;
+ margin-right: auto;
+ z-index: $z-index-modal;
+}
+
+.inline {
+ min-height: $s-40;
+ width: 100%;
+}
+
+.hide {
+ display: none;
+}
+
+.content {
+ @include flexRow;
+}
+
+.text {
+ @include titleTipography;
+}
+
+.inline-actions {
+}
+
+.bottom-actions {
+}
+
+.actions {
+}
+
+.action-btn {
+ @extend .button-tertiary;
+ height: $s-32;
+ width: $s-32;
+ color: black;
+ svg {
+ @extend .button-icon-small;
+ }
+}
+
+.btn-close {
+ @extend .button-tertiary;
+ height: $s-32;
+ width: $s-32;
+ svg {
+ @extend .button-icon-small;
+ stroke: black;
+ }
+}
diff --git a/frontend/src/app/main/ui/modal.cljs b/frontend/src/app/main/ui/modal.cljs
index 1562543aa..61b088b78 100644
--- a/frontend/src/app/main/ui/modal.cljs
+++ b/frontend/src/app/main/ui/modal.cljs
@@ -5,7 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.modal
- (:require-macros [app.main.style :refer [css]])
+ (:require-macros [app.main.style :as stl])
(:require
[app.main.data.modal :as dm]
[app.main.features :as features]
@@ -78,8 +78,9 @@
(when-let [component (get components (:type data))]
[:div {:ref wrapper-ref
- :class (dom/classnames (css :modal-wrapper) new-css-system
- :modal-wrapper (not new-css-system))}
+ :class (stl/css-case
+ :modal-wrapper new-css-system
+ :old-css/modal-wrapper (not new-css-system))}
(mf/element component (:props data))])))
(def modal-ref
diff --git a/frontend/src/app/main/ui/onboarding.cljs b/frontend/src/app/main/ui/onboarding.cljs
index f84f91f3f..be1e60510 100644
--- a/frontend/src/app/main/ui/onboarding.cljs
+++ b/frontend/src/app/main/ui/onboarding.cljs
@@ -5,12 +5,15 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.onboarding
+ (:require-macros [app.main.style :as stl])
(:require
+ [app.common.data.macros :as dm]
[app.config :as cf]
[app.main.data.events :as ev]
[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]
@@ -30,80 +33,178 @@
(mf/defc onboarding-welcome
[{:keys [next] :as props}]
- (let [go-next
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ go-next
(fn []
(send-event "onboarding-step1-continue")
(next))]
- [: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")]]
+ (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.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 {: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.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 :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"}]]])))
(mf/defc onboarding-before-start
[{:keys [next] :as props}]
- (let [go-next
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ go-next
(fn []
(send-event "onboarding-step2-continue")
(next))]
- [: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")]]
+ (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.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 {: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.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 :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"}]]])))
(mf/defc onboarding-modal
{::mf/register modal/components
::mf/register-as :onboarding}
[_]
- (let [slide (mf/use-state :start)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ slide (mf/use-state :start)
klass (mf/use-state "fadeInDown")
navigate
@@ -124,9 +225,17 @@
(fn []
(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.modal-overlay
+ [:div.animated {:class @klass}
+ (case @slide
+ :start [:& onboarding-welcome {:next #(navigate :opensource)}]
+ :opensource [:& onboarding-before-start {:next skip}])]])))
diff --git a/frontend/src/app/main/ui/onboarding.scss b/frontend/src/app/main/ui/onboarding.scss
new file mode 100644
index 000000000..0ff0507a7
--- /dev/null
+++ b/frontend/src/app/main/ui/onboarding.scss
@@ -0,0 +1,106 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+}
+
+.modal-container {
+ @extend .modal-container-base;
+ position: relative;
+ display: flex;
+ padding: 0;
+ margin: 0;
+ min-width: $s-712;
+ border: $s-1 solid var(--modal-border-color);
+}
+
+.modal-left {
+ width: $s-284;
+ img {
+ width: $s-284;
+ height: 100%;
+ border-radius: $br-8 0 0 $br-8;
+ }
+}
+
+.modal-right {
+ @include flexColumn;
+ position: relative;
+ flex-grow: 1;
+ padding: $s-32;
+}
+
+.release {
+ @include titleTipography;
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: $s-8;
+ color: var(--modal-text-foreground-color);
+}
+
+.modal-content {
+ @include flexColumn;
+ @include titleTipography;
+ gap: $s-24;
+ flex-grow: 1;
+ margin-bottom: $s-24;
+}
+
+.modal-title {
+ @include bigTitleTipography;
+ color: var(--modal-title-foreground-color);
+}
+
+.modal-info {
+ @include flexColumn;
+}
+
+.modal-text {
+ @include titleTipography;
+}
+
+.property-block {
+ @include flexRow;
+ gap: $s-16;
+ margin-bottom: $s-24;
+ img {
+ @include flexCenter;
+ height: $s-40;
+ width: $s-40;
+ }
+}
+
+.modal-link {
+ @include titleTipography;
+ color: var(--modal-link-foreground-color);
+ margin: 0;
+}
+
+.text-wrapper {
+ @include flexColumn;
+}
+
+.property-title a {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+}
+
+.property-description {
+ @include titleTipography;
+ color: var(--modal-text-foreground-color);
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: flex-end;
+ button {
+ @extend .modal-accept-btn;
+ }
+}
diff --git a/frontend/src/app/main/ui/onboarding/newsletter.cljs b/frontend/src/app/main/ui/onboarding/newsletter.cljs
index 33b465840..c147a7d5e 100644
--- a/frontend/src/app/main/ui/onboarding/newsletter.cljs
+++ b/frontend/src/app/main/ui/onboarding/newsletter.cljs
@@ -5,11 +5,14 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.onboarding.newsletter
+ (:require-macros [app.main.style :as stl])
(:require
[app.main.data.messages :as dm]
[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]))
@@ -17,9 +20,10 @@
{::mf/register modal/components
::mf/register-as :onboarding-newsletter-modal}
[]
- (let [message (tr "onboarding.newsletter.acceptance-message")
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ message (tr "onboarding.newsletter.acceptance-message")
newsletter-updates (mf/use-state false)
- newsletter-news (mf/use-state false)
+ newsletter-news (mf/use-state false)
toggle
(mf/use-callback
(fn [option]
@@ -35,27 +39,78 @@
(modal/show {:type :onboarding-team})
(du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))]
- [: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"}]]]))
+ (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 :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-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"}]]])
+ ))
diff --git a/frontend/src/app/main/ui/onboarding/newsletter.scss b/frontend/src/app/main/ui/onboarding/newsletter.scss
new file mode 100644
index 000000000..a407dcfa8
--- /dev/null
+++ b/frontend/src/app/main/ui/onboarding/newsletter.scss
@@ -0,0 +1,82 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+}
+
+.modal-container {
+ @extend .modal-container-base;
+ position: relative;
+ min-width: $s-712;
+ border: $s-1 solid var(--modal-border-color);
+}
+
+.modal-header {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-top: $s-80;
+ margin-bottom: $s-32;
+}
+
+.modal-title {
+ @include bigTitleTipography;
+ text-align: center;
+ color: var(--modal-title-foreground-color);
+ margin-bottom: $s-16;
+}
+
+.modal-text {
+ @include titleTipography;
+ color: var(--modal-text-foreground-color);
+ margin: 0;
+}
+
+.modal-content {
+ @include flexColumn;
+ @include titleTipography;
+ gap: $s-32;
+ margin-bottom: $s-24;
+}
+
+.newsletter-options {
+ @include flexColumn;
+ gap: $s-16;
+}
+
+.input-wrapper {
+ @extend .input-checkbox;
+}
+
+.modal-info {
+ @include flexColumn;
+ gap: $s-16;
+ margin-bottom: $s-32;
+}
+
+.modal-link {
+ @include titleTipography;
+ color: var(--modal-link-foreground-color);
+ margin: 0;
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: flex-end;
+ button {
+ @extend .modal-accept-btn;
+ }
+}
+
+.deco {
+ position: absolute;
+ width: 183px;
+ top: -106px;
+ left: 261px;
+}
diff --git a/frontend/src/app/main/ui/onboarding/questions.cljs b/frontend/src/app/main/ui/onboarding/questions.cljs
index ca5d1fb08..1f5d4b9f4 100644
--- a/frontend/src/app/main/ui/onboarding/questions.cljs
+++ b/frontend/src/app/main/ui/onboarding/questions.cljs
@@ -6,12 +6,14 @@
(ns app.main.ui.onboarding.questions
"External form for onboarding questions."
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[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]
@@ -19,67 +21,140 @@
(mf/defc step-container
[{:keys [form step on-next on-prev children] :as props}]
- [:& 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"}]]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
- (when on-prev
- [:div.step-prev
- [:button {:on-click on-prev} (tr "questions.previous")]])]])
+ (if new-css-system
+ [:& fm/form {:form form :on-submit on-next}
+ [:div {:class (stl/css :paginator)} (str/ffmt "%/4" step)]
+
+ children
+
+ [:div {:class (stl/css :action-buttons)}
+
+ (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")]])]])))
(s/def ::questions-form-step-1
(s/keys :req-un [::planning]))
(mf/defc step-1
[{:keys [on-next form] :as props}]
- [:& 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}]])
+ (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}]])))
(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}]
- [:& step-container {:form form :step 2 :on-next on-next :on-prev on-prev}
- [:h3 (tr "questions.describe-your-experience-working-on")]
+ (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")]
- [: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 {: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.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 {: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.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}]]]
+
+
+ [:& 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}]])))
(s/def ::questions-form-step-3
(s/keys :req-un [::experience-design-tool]
@@ -95,7 +170,8 @@
(mf/defc step-3
[{:keys [on-next on-prev form] :as props}]
- (let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ 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])]
@@ -104,20 +180,40 @@
(swap! form d/dissoc-in [:data :experience-design-tool-other])
(swap! form d/dissoc-in [:errors :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")}]]]))
+ (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}]
+
+ [:& 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")}]]])))
(s/def ::questions-form-step-4
(s/keys :req-un [::team-size ::role]
@@ -133,7 +229,8 @@
(mf/defc step-4
[{:keys [on-next on-prev form] :as props}]
- (let [role (dm/get-in @form [:data :role])
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ role (dm/get-in @form [:data :role])
on-role-change
(fn [_ _]
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])]
@@ -142,83 +239,122 @@
(swap! form d/dissoc-in [:data :role-other])
(swap! form d/dissoc-in [:errors :role-other])))))]
- [:& 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")}]]
+ (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")}]
- [: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}]]]
+
+
+ [:& 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}]])))
(mf/defc questions
[{:keys []}]
- (let [container (mf/use-ref)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ container (mf/use-ref)
step (mf/use-state 1)
clean-data (mf/use-state {})
;; Forms are initialized here because we can go back and forth between the steps
;; and we want to keep the filled info
step-1-form (fm/use-form
- :initial {}
- :spec ::questions-form-step-1)
+ :initial {}
+ :spec ::questions-form-step-1)
step-2-form (fm/use-form
- :initial {}
- :spec ::questions-form-step-2)
+ :initial {}
+ :spec ::questions-form-step-2)
step-3-form (fm/use-form
- :initial {}
- :validators [step-3-form-validator]
- :spec ::questions-form-step-3)
+ :initial {}
+ :validators [step-3-form-validator]
+ :spec ::questions-form-step-3)
step-4-form (fm/use-form
- :initial {}
- :validators [step-4-form-validator]
- :spec ::questions-form-step-4)
+ :initial {}
+ :validators [step-4-form-validator]
+ :spec ::questions-form-step-4)
on-next
(mf/use-fn
- (fn [form]
- (swap! step inc)
- (swap! clean-data merge (:clean-data @form))))
+ (fn [form]
+ (swap! step inc)
+ (swap! clean-data merge (:clean-data @form))))
on-prev
(mf/use-fn
- (fn []
- (swap! step dec)))
+ (fn []
+ (swap! step dec)))
on-submit
(mf/use-fn
- (mf/deps @clean-data)
- (fn [form]
- (let [questionnaire (merge @clean-data (:clean-data @form))]
- (reset! clean-data questionnaire)
- (st/emit! (du/mark-questions-as-answered questionnaire)))))]
+ (mf/deps @clean-data)
+ (fn [form]
+ (let [questionnaire (merge @clean-data (:clean-data @form))]
+ (reset! clean-data questionnaire)
+ (st/emit! (du/mark-questions-as-answered questionnaire)))))]
- [: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
+ (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}])]]]]))
+ 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}])]]]])))
diff --git a/frontend/src/app/main/ui/onboarding/questions.scss b/frontend/src/app/main/ui/onboarding/questions.scss
new file mode 100644
index 000000000..e2024f7dd
--- /dev/null
+++ b/frontend/src/app/main/ui/onboarding/questions.scss
@@ -0,0 +1,72 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+}
+
+.modal-container {
+ @extend .modal-container-base;
+ min-width: $s-512;
+ position: relative;
+ border: $s-1 solid var(--modal-border-color);
+}
+
+// STEP CONTAINER
+.paginator {
+ @include titleTipography;
+ position: absolute;
+ top: $s-8;
+ right: $s-8;
+ padding: $s-4;
+ border-radius: $br-6;
+ color: var(--color-foreground-secondary);
+}
+
+.action-buttons {
+ @extend .modal-action-btns;
+ margin-top: $s-32;
+}
+.next-button {
+ @extend .modal-accept-btn;
+}
+
+.prev-button {
+ @extend .modal-cancel-btn;
+}
+
+// STEP 1
+
+.header-image {
+ height: auto;
+ width: $s-200;
+}
+
+.modal-title {
+ @include bigTitleTipography;
+ color: var(--modal-title-foreground-color);
+ margin: $s-32 0 $s-8 0;
+}
+
+.modal-subtitle {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+}
+
+// STEP-2
+
+.modal-text {
+ @include titleTipography;
+ color: var(--modal-text-foreground-color);
+ margin: 0;
+}
+
+.modal-question {
+ @include flexColumn;
+ margin-top: $s-32;
+}
diff --git a/frontend/src/app/main/ui/onboarding/team_choice.cljs b/frontend/src/app/main/ui/onboarding/team_choice.cljs
index 06785c02a..c71c62410 100644
--- a/frontend/src/app/main/ui/onboarding/team_choice.cljs
+++ b/frontend/src/app/main/ui/onboarding/team_choice.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.onboarding.team-choice
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.spec :as us]
[app.main.data.dashboard :as dd]
@@ -14,6 +15,7 @@
[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]
@@ -28,31 +30,64 @@
(mf/defc team-modal-right
[]
- [: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")]]]])
+ (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")]]]])))
(mf/defc onboarding-team-modal
{::mf/register modal/components
::mf/register-as :onboarding-team}
[]
- (let [form (fm/use-form :spec ::team-form
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ 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"))])
@@ -73,36 +108,77 @@
:step 1}))))
teams (mf/deref refs/teams)]
- (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")}]
+ (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}
- [:& fm/submit-button*
- {:label (tr "onboarding.choice.team-up.continue-creating-team")}]]
+ [:& fm/input {:type "text"
+ :class (stl/css :team-name-input)
+ :name :name
+ :placeholder "Team name"
+ :label (tr "onboarding.choice.team-up.create-team-placeholder")}]
- [: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)}
+ [:& 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
- [: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"]
+ [: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"]]]
- [: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)))))
+
+ (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/submit-button*
+ {:label (tr "onboarding.choice.team-up.continue-creating-team")}]]
+
+ [:h2.title (tr "onboarding.choice.team-up.start-without-a-team")]
+ [:p.info (tr "onboarding.choice.team-up.start-without-a-team-description")]
+
+ [: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))))))
(defn get-available-roles
[]
@@ -121,14 +197,15 @@
{::mf/register modal/components
::mf/register-as :onboarding-team-invitations}
[{:keys [name] :as props}]
- (let [initial (mf/use-memo (constantly
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ initial (mf/use-memo (constantly
{:role "editor"
:name name}))
form (fm/use-form :spec ::invite-form
:initial initial)
params (:clean-data @form)
emails (:emails params)
-
+
roles (mf/use-memo #(get-available-roles))
on-success
@@ -167,7 +244,7 @@
:on-error (partial on-error form)}
params (:clean-data @form)
emails (:emails params)]
-
+
(st/emit! (if (> (count emails) 0)
;; If the user is only inviting to itself we don't call to create-team-with-invitations
(dd/create-team-with-invitations (with-meta params mdata))
@@ -178,7 +255,7 @@
:role (:role params)
:name name
:step 2})))))
-
+
on-submit
(mf/use-callback
(fn [_]
@@ -188,49 +265,96 @@
(on-invite-now form)
(on-invite-later form)))))]
- [: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")]
+ (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")]
- [:& 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}]]
+ [: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}]]
- [:& 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 {: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.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"]
+ [: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")]
- [: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"}]]]))
+ [:& 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"}]]])))
diff --git a/frontend/src/app/main/ui/onboarding/team_choice.scss b/frontend/src/app/main/ui/onboarding/team_choice.scss
new file mode 100644
index 000000000..1ebf06798
--- /dev/null
+++ b/frontend/src/app/main/ui/onboarding/team_choice.scss
@@ -0,0 +1,145 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+}
+
+.modal-container {
+ @extend .modal-container-base;
+ padding: 0;
+ display: flex;
+ position: relative;
+ min-width: $s-712;
+ border: $s-1 solid var(--modal-border-color);
+}
+
+.modal-left {
+ width: $s-356;
+ padding: $s-48 $s-28 $s-48 $s-48;
+}
+
+.first-block,
+.second-block {
+ @include flexColumn;
+ width: 100%;
+}
+
+.first-block {
+ margin-bottom: $s-72;
+}
+
+.modal-right {
+ width: $s-356;
+ padding: $s-48;
+ background-color: var(--color-background-tertiary);
+}
+
+.modal-title {
+ @include bigTitleTipography;
+ color: var(--modal-title-foreground-color);
+ margin-bottom: $s-8;
+}
+
+.modal-subtitle {
+ @include tabTitleTipography;
+ color: var(--modal-title-foreground-color);
+ margin-bottom: $s-8;
+}
+
+.modal-text,
+.modal-hint {
+ @include titleTipography;
+ color: var(--modal-text-foreground-color);
+ margin: 0;
+}
+.modal-hint {
+ margin-top: $s-24;
+}
+.modal-form {
+ margin: $s-24 0;
+}
+
+.team-name-input {
+ @extend .input-element-label;
+ label {
+ @include flexColumn;
+ @include titleTipography;
+ align-items: flex-start;
+ width: 100%;
+ border: none;
+ background-color: transparent;
+ height: 100%;
+
+ input {
+ @include titleTipography;
+ margin-top: $s-8;
+ }
+ }
+}
+
+.role-select {
+ @include flexColumn;
+ .role-title {
+ @include titleTipography;
+ margin: 0;
+ color: var(--modal-title-foreground-color);
+ }
+}
+
+.invitation-row {
+ margin-top: $s-8;
+ margin-bottom: $s-24;
+}
+
+.paginator {
+ @include titleTipography;
+ position: absolute;
+ top: $s-8;
+ right: $s-8;
+ padding: $s-4;
+ border-radius: $br-6;
+ color: var(--color-foreground-secondary);
+}
+
+.action-buttons {
+ @extend .modal-action-btns;
+ justify-content: flex-start;
+ margin-top: $s-24;
+}
+
+.accept-button {
+ @extend .modal-accept-btn;
+}
+
+.back-button {
+ @extend .modal-cancel-btn;
+}
+
+.team-features {
+ @include flexColumn;
+ gap: $s-24;
+ margin-top: $s-24;
+}
+
+.feature {
+ @include flexRow;
+ gap: $s-8;
+}
+
+.icon {
+ @include flexCenter;
+ height: $s-32;
+ width: $s-32;
+ border-radius: $br-circle;
+ background-color: var(--color-accent-primary);
+ svg {
+ @extend .button-icon;
+ stroke: var(--color-background-tertiary);
+ }
+}
diff --git a/frontend/src/app/main/ui/onboarding/templates.cljs b/frontend/src/app/main/ui/onboarding/templates.cljs
index 01ed35345..2ce17a7d8 100644
--- a/frontend/src/app/main/ui/onboarding/templates.cljs
+++ b/frontend/src/app/main/ui/onboarding/templates.cljs
@@ -44,8 +44,7 @@
(fn [error]
(js/console.log "error" error))
(fn []
- (reset! downloading? false)))))
- ]
+ (reset! downloading? false)))))]
[:div.template-item
[:div.template-item-content
diff --git a/frontend/src/app/main/ui/releases.scss b/frontend/src/app/main/ui/releases.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs
index 3e4947ce9..617b76e60 100644
--- a/frontend/src/app/main/ui/settings/access_tokens.cljs
+++ b/frontend/src/app/main/ui/settings/access_tokens.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.settings.access-tokens
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.spec :as us]
[app.main.data.messages :as dm]
@@ -13,6 +14,7 @@
[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]]
@@ -49,7 +51,8 @@
{::mf/register modal/components
::mf/register-as :access-token}
[]
- (let [form (fm/use-form
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ form (fm/use-form
:initial initial-data
:spec ::access-token-form
:validators [name-validator
@@ -61,38 +64,38 @@
on-success
(mf/use-fn
- (mf/deps created)
- (fn [_]
- (let [message (tr "dashboard.access-tokens.create.success")]
- (st/emit! (du/fetch-access-tokens)
- (dm/success message)
- (reset! created? true)))))
+ (mf/deps created)
+ (fn [_]
+ (let [message (tr "dashboard.access-tokens.create.success")]
+ (st/emit! (du/fetch-access-tokens)
+ (dm/success message)
+ (reset! created? true)))))
on-close
(mf/use-fn
- (mf/deps created)
- (fn [_]
- (reset! created? false)
- (st/emit! (modal/hide))))
+ (mf/deps created)
+ (fn [_]
+ (reset! created? false)
+ (st/emit! (modal/hide))))
on-error
(mf/use-fn
- (fn [_]
- (st/emit! (dm/error (tr "errors.generic"))
- (modal/hide))))
+ (fn [_]
+ (st/emit! (dm/error (tr "errors.generic"))
+ (modal/hide))))
on-submit
(mf/use-fn
- (fn [form]
- (let [cdata (:clean-data @form)
- mdata {:on-success (partial on-success form)
- :on-error (partial on-error form)}
- expiration (:expiration-date cdata)
- params (cond-> {:name (:name cdata)
- :perms (:perms cdata)}
- (not= "never" expiration) (assoc :expiration expiration))]
- (st/emit! (du/create-access-token
- (with-meta params mdata))))))
+ (fn [form]
+ (let [cdata (:clean-data @form)
+ mdata {:on-success (partial on-success form)
+ :on-error (partial on-error form)}
+ expiration (:expiration-date cdata)
+ params (cond-> {:name (:name cdata)
+ :perms (:perms cdata)}
+ (not= "never" expiration) (assoc :expiration expiration))]
+ (st/emit! (du/create-access-token
+ (with-meta params mdata))))))
copy-token
(mf/use-fn
@@ -104,70 +107,143 @@
:content (tr "dashboard.access-tokens.copied-success")
:timeout 1000}))))]
- [:div.modal-overlay
- [:div.modal-container.access-tokens-modal
- [:& fm/form {:form form :on-submit on-submit}
+ (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.modal-header
- [:div.modal-header-title
- [:h2 (tr "modals.create-access-token.title")]]
+ [:div {:class (stl/css :modal-header)}
+ [:h2 {:class (stl/css :modal-title)} (tr "modals.create-access-token.title")]
- [:div.modal-close-button
- {:on-click on-close} i/close]]
+ [:button {:class (stl/css :modal-close-btn)
+ :on-click on-close} i/close-refactor]]
- [: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"
+ [: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?
- :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"))])]
+ :label (tr "modals.create-access-token.name.label")
+ :placeholder (tr "modals.create-access-token.name.placeholder")}]]
- [: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}
+ [: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"))])]
- i/copy]])]]]
+ [: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 :icon)}
+ i/clipboard-refactor]])]]
- [: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")}]])]]]]]))
+ [: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")}]])]]]]])))
(mf/defc access-tokens-hero
[]
diff --git a/frontend/src/app/main/ui/settings/access_tokens.scss b/frontend/src/app/main/ui/settings/access_tokens.scss
new file mode 100644
index 000000000..a9d63c3de
--- /dev/null
+++ b/frontend/src/app/main/ui/settings/access_tokens.scss
@@ -0,0 +1,82 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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;
+
+ .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;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/settings/change_email.cljs b/frontend/src/app/main/ui/settings/change_email.cljs
index 996d4668c..391fa4475 100644
--- a/frontend/src/app/main/ui/settings/change_email.cljs
+++ b/frontend/src/app/main/ui/settings/change_email.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.settings.change-email
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dma]
@@ -15,6 +16,7 @@
[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]]
@@ -74,7 +76,8 @@
{::mf/register modal/components
::mf/register-as :change-email}
[]
- (let [profile (mf/deref refs/profile)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ profile (mf/deref refs/profile)
form (fm/use-form :spec ::email-change-form
:validators [email-equality]
:initial profile)
@@ -85,7 +88,7 @@
(mf/use-callback
(mf/deps profile)
(partial on-submit profile))
-
+
on-email-change
(mf/use-callback
(fn [_ _]
@@ -96,41 +99,81 @@
(when (and different-emails-error? (= email-1 email-2))
(swap! form d/dissoc-in [:errors :email-2])))))]
- [:div.modal-overlay
- [:div.modal-container.change-email-modal.form-container
- [:& fm/form {:form form
- :on-submit on-submit}
+ (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.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 {: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.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.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 {:class (stl/css :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.modal-footer
- [:div.action-buttons {:data-test "change-email-submit"}
- [:> fm/submit-button*
- {:label (tr "modals.change-email.submit")}]]]]]]))
+ [:div {:class (stl/css :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 {: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")}]]]]]])
+ ))
diff --git a/frontend/src/app/main/ui/settings/change_email.scss b/frontend/src/app/main/ui/settings/change_email.scss
new file mode 100644
index 000000000..6b6b760c9
--- /dev/null
+++ b/frontend/src/app/main/ui/settings/change_email.scss
@@ -0,0 +1,53 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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;
+
+ .fields-row {
+ @include flexColumn;
+ .select-title {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+ }
+ }
+ }
+
+ .modal-footer {
+ .action-buttons {
+ @extend .modal-action-btns;
+ button {
+ @extend .modal-accept-btn;
+ }
+ .cancel-button {
+ @extend .modal-cancel-btn;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/settings/delete_account.cljs b/frontend/src/app/main/ui/settings/delete_account.cljs
index 9a1961f1a..5f13bcf85 100644
--- a/frontend/src/app/main/ui/settings/delete_account.cljs
+++ b/frontend/src/app/main/ui/settings/delete_account.cljs
@@ -5,11 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.settings.delete-account
+ (:require-macros [app.main.style :as stl])
(:require
[app.main.data.messages :as dm]
[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]]
@@ -27,33 +29,62 @@
{::mf/register modal/components
::mf/register-as :delete-account}
[]
- (let [on-close
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ on-close
(mf/use-callback #(st/emit! (modal/hide)))
on-accept
(mf/use-callback
#(st/emit! (modal/hide)
(du/request-account-deletion
- (with-meta {} {:on-error on-error}))))]
+ (with-meta {} {:on-error on-error}))))]
- [: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]]
+ (if new-css-system
+ [:div {:class (stl/css :modal-overlay)}
+ [:div {:class (stl/css :modal-container)}
- [:div.modal-content
- [:& msgs/inline-banner
- {:type :warning
- :content (tr "modals.delete-account.info")}]]
+ [:div {:class (stl/css :modal-header)}
- [: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")]]]]]))
+ [: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-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")]]]]])))
diff --git a/frontend/src/app/main/ui/settings/delete_account.scss b/frontend/src/app/main/ui/settings/delete_account.scss
new file mode 100644
index 000000000..e12ff29a8
--- /dev/null
+++ b/frontend/src/app/main/ui/settings/delete_account.scss
@@ -0,0 +1,57 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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;
+
+ .fields-row {
+ @include flexColumn;
+ .select-title {
+ @include titleTipography;
+ color: var(--modal-title-foreground-color);
+ }
+ }
+ }
+
+ .modal-footer {
+ .action-buttons {
+ @extend .modal-action-btns;
+
+ .cancel-button {
+ @extend .modal-cancel-btn;
+ }
+ .accept-button {
+ @extend .modal-accept-btn;
+ &.danger {
+ @extend .modal-danger-btn;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/viewer/login.cljs b/frontend/src/app/main/ui/viewer/login.cljs
index 7a130a7a4..46054f8f8 100644
--- a/frontend/src/app/main/ui/viewer/login.cljs
+++ b/frontend/src/app/main/ui/viewer/login.cljs
@@ -51,7 +51,6 @@
(set-current-section :register-validate))]
(mf/with-effect []
(swap! storage assoc :redirect-url uri))
-
[:div.modal-overlay
[:div.modal-container.login-register
[:div.title
diff --git a/frontend/src/app/main/ui/workspace/left_header.scss b/frontend/src/app/main/ui/workspace/left_header.scss
index 665b7c779..b89a2c0e2 100644
--- a/frontend/src/app/main/ui/workspace/left_header.scss
+++ b/frontend/src/app/main/ui/workspace/left_header.scss
@@ -37,7 +37,7 @@
cursor: pointer;
}
.file-name {
- @include titleBigTipography;
+ @include medTitleTipography;
text-transform: none;
color: var(--title-foreground-color-hover);
}
diff --git a/frontend/src/app/main/ui/workspace/libraries.scss b/frontend/src/app/main/ui/workspace/libraries.scss
index 2db3097f9..b1efd730e 100644
--- a/frontend/src/app/main/ui/workspace/libraries.scss
+++ b/frontend/src/app/main/ui/workspace/libraries.scss
@@ -175,7 +175,7 @@
grid-column: span 3;
grid-template-columns: repeat(auto-fill, minmax($s-160, 1fr));
grid-gap: $s-24;
- font-size: $fs12;
+ font-size: $fs-12;
margin-top: $s-16;
.libraries-updates-item {
diff --git a/frontend/src/app/main/ui/workspace/nudge.cljs b/frontend/src/app/main/ui/workspace/nudge.cljs
index 0d6e079e1..6e59f4618 100644
--- a/frontend/src/app/main/ui/workspace/nudge.cljs
+++ b/frontend/src/app/main/ui/workspace/nudge.cljs
@@ -5,12 +5,14 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.nudge
+ (:require-macros [app.main.style :as stl])
(:require
[app.main.data.modal :as modal]
[app.main.data.workspace :as dw]
[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]]
@@ -30,7 +32,8 @@
{::mf/register modal/components
::mf/register-as :nudge-option}
[]
- (let [profile (mf/deref refs/profile)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ 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 %})))
@@ -40,21 +43,45 @@
(->> (events/listen js/document EventType.KEYDOWN on-keydown)
(partial events/unlistenByKey)))
- [: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}]]]]]]))
+ (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}]]]]]])))
diff --git a/frontend/src/app/main/ui/workspace/nudge.scss b/frontend/src/app/main/ui/workspace/nudge.scss
new file mode 100644
index 000000000..042f64c2f
--- /dev/null
+++ b/frontend/src/app/main/ui/workspace/nudge.scss
@@ -0,0 +1,42 @@
+// 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
+
+@import "refactor/common-refactor.scss";
+
+.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-msg {
+ @include titleTipography;
+ }
+ .input-wrapper {
+ @extend .input-with-label;
+ label {
+ text-transform: none;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/workspace/right_header.scss b/frontend/src/app/main/ui/workspace/right_header.scss
index b16d32f45..65c28c98d 100644
--- a/frontend/src/app/main/ui/workspace/right_header.scss
+++ b/frontend/src/app/main/ui/workspace/right_header.scss
@@ -97,7 +97,7 @@
min-width: $s-68;
padding: 0 $s-8;
margin: 0;
- color: var(--modal-foreground-color);
+ color: var(--modal-title-foreground-color);
}
}
.reset-btn {
diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs
index ac618f9e8..9a67ca682 100644
--- a/frontend/src/app/main/ui/workspace/sidebar.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar.cljs
@@ -66,8 +66,8 @@
:id "left-sidebar-aside"
:data-size size
:class (stl/css-case new-css-system
- :old-css/settings-bar true
- :old-css/settings-bar-left true
+ :global/settings-bar true
+ :global/settings-bar-left true
:left-settings-bar true
:global/two-row (<= size 300)
:global/three-row (and (> size 300) (<= size 400))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs
index 546975055..096fa42eb 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs
@@ -5,7 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.assets.groups
- (:require-macros [app.main.style :refer [css]])
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
@@ -47,17 +47,17 @@
on-close-menu
(mf/use-fn #(swap! menu-state cmm/close-context-menu))]
(if new-css-system
- [:div {:class (dom/classnames (css :group-title) true)
+ [:div {:class (stl/css :group-title)
:on-context-menu on-context-menu}
[:& title-bar {:collapsable? true
:collapsed? (not group-open?)
:clickable-all? true
:on-collapsed on-fold-group
:title (mf/html [:* (when-not (empty? other-path)
- [:span {:class (dom/classnames (css :pre-path) true)
+ [:span {:class (stl/css :pre-path)
:title (when truncated path)}
other-path "\u00A0\u2022\u00A0"])
- [:span {:class (dom/classnames (css :path) true)
+ [:span {:class (stl/css :path)
:title (when truncated path)}
last-path]])}]
[:& cmm/assets-context-menu
@@ -120,7 +120,8 @@
::mf/register-as :name-group-dialog}
[{:keys [path last-path accept] :as ctx
:or {path "" last-path ""}}]
- (let [initial (mf/use-memo
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ initial (mf/use-memo
(mf/deps last-path)
(constantly {:asset-name last-path}))
form (fm/use-form :spec ::name-group-form
@@ -141,34 +142,69 @@
(accept asset-name)
(accept path asset-name))
(modal/hide!))))]
+ (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)}
+ (if create?
+ (tr "workspace.assets.create-group")
+ (tr "workspace.assets.rename-group"))]
+ [:button {:class (stl/css :modal-close-btn)
+ :on-click on-close} i/close-refactor]]
- [:div.modal-overlay
- [:div.modal-container.confirm-dialog
- [:div.modal-header
- [:div.modal-header-title
- [:h2 (if create?
- (tr "workspace.assets.create-group")
- (tr "workspace.assets.rename-group"))]]
- [:div.modal-close-button
- {:on-click on-close} i/close]]
+ [:div {:class (stl/css :modal-content)}
+ [:& fm/form {:form form :on-submit on-accept}
+ [:& fm/input {:name :asset-name
+ :class (stl/css :input-wrapper)
+ :auto-focus? true
+ :label (tr "workspace.assets.group-name")
+ :hint (tr "workspace.assets.create-group-hint")}]]]
- [:div.modal-content.generic-form
- [:& fm/form {:form form :on-submit on-accept}
- [:& fm/input {:name :asset-name
- :auto-focus? true
- :label (tr "workspace.assets.group-name")
- :hint (tr "workspace.assets.create-group-hint")}]]]
+ [: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-close}]
- [:div.modal-footer
- [:div.action-buttons
- [:input.cancel-button
- {:type "button"
- :value (tr "labels.cancel")
- :on-click on-close}]
+ [:input
+ {:type "button"
+ :class (stl/css-case :accept-btn true
+ :global/disabled (not (:valid @form) ))
+ :disabled (not (:valid @form))
+ :value (if create? (tr "labels.create") (tr "labels.rename"))
+ :on-click on-accept}]]]]]
- [:input.accept-button.primary
- {:type "button"
- :class (when-not (:valid @form) "btn-disabled")
- :disabled (not (:valid @form))
- :value (if create? (tr "labels.create") (tr "labels.rename"))
- :on-click on-accept}]]]]]))
+
+ [:div.modal-overlay
+ [:div.modal-container.confirm-dialog
+ [:div.modal-header
+ [:div.modal-header-title
+ [:h2 (if create?
+ (tr "workspace.assets.create-group")
+ (tr "workspace.assets.rename-group"))]]
+ [:div.modal-close-button
+ {:on-click on-close} i/close]]
+
+ [:div.modal-content.generic-form
+ [:& fm/form {:form form :on-submit on-accept}
+ [:& fm/input {:name :asset-name
+ :auto-focus? true
+ :label (tr "workspace.assets.group-name")
+ :hint (tr "workspace.assets.create-group-hint")}]]]
+
+ [:div.modal-footer
+ [:div.action-buttons
+ [:input.cancel-button
+ {:type "button"
+ :value (tr "labels.cancel")
+ :on-click on-close}]
+
+ [:input.accept-button.primary
+ {:type "button"
+ :class (when-not (:valid @form) "btn-disabled")
+ :disabled (not (:valid @form))
+ :value (if create? (tr "labels.create") (tr "labels.rename"))
+ :on-click on-accept}]]]]])))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss
index 88eb0e6cd..93235d3ba 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss
@@ -19,3 +19,41 @@
color: var(--title-foreground-color-hover);
}
}
+
+.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-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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index cda611ae5..8ff5e68f4 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -2247,6 +2247,12 @@ msgstr "Create team and send invites"
msgid "onboarding.choice.team-up.create-team-without-inviting"
msgstr "Create team without inviting"
+msgid "onboarding.choice.team-up.create-team-and-invite"
+msgstr "Create team & invite"
+
+msgid "onboarding.choice.team-up.create-team-without-invite"
+msgstr "Create team"
+
msgid "onboarding.choice.team-up.create-team-and-send-invites-description"
msgstr "You'll be able to invite later"
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index c547166cb..046bb34a3 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -2300,6 +2300,12 @@ msgstr "Crear equipo y enviar invitaciones"
msgid "onboarding.choice.team-up.create-team-without-inviting"
msgstr "Crear equipo sin invitar"
+msgid "onboarding.choice.team-up.create-team-and-invite"
+msgstr "Crear equipo e invitar"
+
+msgid "onboarding.choice.team-up.create-team-without-invite"
+msgstr "Crear equipo"
+
msgid "onboarding.choice.team-up.create-team-and-send-invites-description"
msgstr "Podrás enviar invitaciones después"