♻️ Refactor import modal

This commit is contained in:
Eva Marco 2026-07-24 09:38:39 +02:00
parent c7a00c6829
commit e9af139c0e
3 changed files with 477 additions and 278 deletions

View File

@ -18,11 +18,18 @@
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.select :refer [select*]]
[app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]]
[app.main.ui.ds.foundations.assets.raw-svg :as rsvg :refer [raw-svg*]]
[app.main.ui.ds.foundations.typography :as t]
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
[app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.ds.product.loader :refer [loader*]]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.notifications.context-notification :refer [context-notification]]
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
[app.main.worker :as mw]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -57,7 +64,7 @@
{::mf/forward-ref true}
[{:keys [project-id on-finish-import]} external-ref]
(let [on-file-selected (use-import-file project-id on-finish-import)]
[:form.import-file {:aria-hidden "true"}
[:form {:aria-hidden "true"}
[:& file-uploader {:accept ".penpot,.zip"
:multi true
:ref external-ref
@ -217,13 +224,21 @@
;; FIXME: rename to format
format (:type entry)
loading? (or (= :analyze status)
loading? false #_(or (= :analyze status)
(= :import-progress status)
(and is-progress (= :import-ready status)))
analyze-error? (= :analyze-error status)
import-success? (= :import-success status)
import-error? (= :import-error status)
import-ready? (= :import-ready status)
analyze-error? true #_(= :analyze-error status)
import-success? false #_(= :import-success status)
import-error? false #_(= :import-error status)
import-ready? false #_(= :import-ready status)
level (cond
import-success? :success
import-ready? :success
import-error? :error
analyze-error? :error
loading? nil
:else :default)
is-shared? (:shared entry)
progress (:progress entry)
@ -272,46 +287,64 @@
:editable (and import-ready? (not editing?)))}
[:div {:class (stl/css :file-name)}
(if loading?
[:> loader* {:width 16 :title (tr "labels.loading")}]
[:div {:class (stl/css-case
:file-icon true
:icon-fill import-ready?)}
(cond
import-ready? deprecated-icon/logo-icon
import-error? deprecated-icon/close
import-success? deprecated-icon/tick
analyze-error? deprecated-icon/close)])
(when loading? [:> loader* {:width 26 :title (tr "labels.loading")}])
(if editing?
[:div {:class (stl/css :file-name-edit)}
[:input {:type "text"
:auto-focus true
:class (stl/css :file-name-input)
;;TODO: Add translation for aria-label
:aria-label "File name"
:default-value (:name entry)
:on-key-press on-edit-key-press
:on-blur on-edit-blur}]]
[:div {:class (stl/css :file-name-label)}
(:name entry)
(when ^boolean is-shared?
[:span {:class (stl/css :icon)}
deprecated-icon/library])])
(if loading?
[:> text* {:class (stl/css :file-name-label)
:as "span"
:typography t/body-medium}
(:name entry)
(when ^boolean is-shared?
[:> icon* {:icon-id i/library :class (stl/css :icon)}])]
[:> context-notification*
{:level level
:appearance :ghost
:class (stl/css :file-name-notification)}
[:> text* {:class (stl/css :file-name-label)
:as "span"
:typography t/body-medium}
(:name entry)
(when ^boolean is-shared?
[:> icon* {:icon-id i/library :class (stl/css :icon)}])]])])
[:div {:class (stl/css :edit-entry-buttons)}
(when ^boolean editable?
[:button {:on-click on-edit'} deprecated-icon/curve])
[:> icon-button* {:on-click on-edit'
:variant "ghost"
:icon-size "s"
:aria-label (tr "labels.edit")
:icon i/curve}])
(when ^boolean can-be-deleted
[:button {:on-click on-delete'} deprecated-icon/delete])]]
[:> icon-button* {:on-click on-delete'
:variant "ghost"
:icon-size "s"
:aria-label (tr "labels.delete")
:icon i/delete}])]]
(cond
analyze-error?
[:div {:class (stl/css :error-message)}
[:> text* {:class (stl/css :error-message)
:as "span"
:typography t/body-small}
(if (some? (:error entry))
(tr (:error entry))
(tr "dashboard.import.analyze-error"))]
import-error?
[:div {:class (stl/css :error-message)}
[:> text* {:class (stl/css :error-message)
:as "span"
:typography t/body-small}
(if (some? (:error entry))
(tr (:error entry))
(tr "labels.error"))]
@ -689,13 +722,17 @@
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title)} (tr "dashboard.import")]
[:button {:class (stl/css :modal-close-btn)
:on-click on-cancel} deprecated-icon/close]]
[:> heading* {:level 2
:typography t/headline-large
:class (stl/css :modal-title)}
(tr "dashboard.import")]
[:> icon-button* {:variant "ghost"
:aria-label (tr "labels.close")
:on-click on-cancel
:class (stl/css :modal-close-btn)
:icon i/close}]]
[:div {:class (stl/css :modal-content)}
(cond
(and (= :analyze status) errors?)
[:& context-notification

View File

@ -4,153 +4,235 @@
//
// Copyright (c) KALEIDOS INC Sucursal en España SL
@use "refactor/common-refactor.scss" as deprecated;
@use "ds/typography.scss" as *;
@use "ds/_borders.scss" as *;
@use "ds/spacing.scss" as *;
@use "ds/_sizes.scss" as *;
@use "ds/_utils.scss" as *;
@use "ds/z-index.scss" as *;
.modal-overlay {
@extend %modal-overlay-base;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
inset-inline-start: 0;
inset-block-start: 0;
block-size: 100%;
inline-size: 100%;
z-index: var(--z-index-set);
background-color: var(--overlay-color);
}
.modal-container {
@extend %modal-container-base;
position: relative;
display: flex;
flex-direction: column;
}
.modal-header {
margin-bottom: deprecated.$s-24;
}
.modal-title {
@include deprecated.uppercase-title-typography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend %modal-close-btn-base;
gap: var(--sp-xxxl);
padding: var(--sp-xxxl);
border-radius: $br-8;
background-color: var(--color-background-primary);
border: $b-2 solid var(--color-background-quaternary);
min-block-size: $sz-192;
inline-size: $sz-512;
max-block-size: calc(10 * px2rem(80));
}
.modal-content {
@include deprecated.body-small-typography;
display: flex;
flex-direction: column;
gap: var(--sp-l);
margin-block-end: var(--sp-xxl);
}
.modal-title {
color: var(--color-foreground-primary);
}
.modal-close-btn {
// %button-tertiary essentials
border-radius: $br-8;
background-color: transparent;
border: $b-2 solid transparent;
color: var(--button-tertiary-foreground-color-rest);
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
inset-block-start: var(--sp-s);
inset-inline-end: px2rem(6);
block-size: $sz-32;
inline-size: $sz-28;
svg {
display: flex;
justify-content: center;
align-items: center;
block-size: $sz-16;
inline-size: $sz-16;
color: transparent;
fill: none;
stroke-width: 1px;
stroke: var(--button-tertiary-foreground-color-rest);
}
&:hover {
background-color: var(--button-tertiary-background-color-hover);
color: var(--button-tertiary-foreground-color-hover);
border-color: var(--button-secondary-border-color-hover);
svg {
stroke: var(--button-tertiary-foreground-color-hover);
}
}
}
.modal-content {
// TODO: Typography does not match any existing DS typography token.
// body-small-typography: line-height 1.4 (DS body-small has line-height 1.3)
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
flex: 1;
overflow: hidden auto;
display: grid;
grid-template-columns: 1fr;
gap: deprecated.$s-16;
margin-bottom: deprecated.$s-24;
min-height: 40px;
gap: var(--sp-l);
margin-block-end: var(--sp-xxl);
min-block-size: px2rem(40);
}
.status-message {
@include deprecated.body-small-typography;
color: var(--modal-title-foreground-color);
// TODO: Typography does not match any existing DS typography token.
// body-small-typography: line-height 1.4 (DS body-small has line-height 1.3)
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
color: var(--color-foreground-primary);
font-style: italic;
}
.action-buttons {
@extend %modal-action-btns;
display: flex;
justify-content: flex-end;
gap: var(--sp-l);
}
.cancel-button {
@extend %modal-cancel-btn;
// %modal-cancel-btn essentials (these are <input type=button> elements)
border-radius: $br-8;
background-color: var(--button-secondary-background-color-rest);
border: $b-1 solid var(--button-secondary-border-color-rest);
color: var(--button-secondary-foreground-color-rest);
display: flex;
justify-content: center;
align-items: center;
padding: var(--sp-s) var(--sp-xxl);
block-size: $sz-32;
margin: 0;
cursor: pointer;
// TODO: Typography does not match any existing DS typography token.
// uppercase-title-typography: 11px, weight 500, line-height 1.2, uppercase
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(11);
font-weight: 500;
line-height: 1.2;
text-transform: uppercase;
&:hover {
background-color: var(--button-secondary-background-color-hover);
border-color: var(--button-secondary-border-color-hover);
color: var(--button-secondary-foreground-color-hover);
}
&:active {
background-color: var(--button-secondary-background-color-active);
border-color: var(--button-secondary-border-color-active);
color: var(--button-secondary-foreground-color-active);
}
&[disabled],
&:disabled {
background-color: var(--button-background-color-disabled);
border-color: var(--button-border-color-disabled);
color: var(--button-foreground-color-disabled);
cursor: unset;
}
}
.accept-btn {
@extend %modal-accept-btn;
// %modal-accept-btn essentials
border-radius: $br-8;
background-color: var(--button-primary-background-color-rest);
border: $b-1 solid var(--button-primary-border-color-rest);
color: var(--button-primary-foreground-color-rest);
display: flex;
justify-content: center;
align-items: center;
padding: var(--sp-s) var(--sp-xxl);
block-size: $sz-32;
margin: 0;
cursor: pointer;
// TODO: Typography does not match any existing DS typography token.
// uppercase-title-typography: 11px, weight 500, line-height 1.2, uppercase
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(11);
font-weight: 500;
line-height: 1.2;
text-transform: uppercase;
&:hover {
background-color: var(--button-primary-background-color-hover);
border-color: var(--button-primary-border-color-hover);
color: var(--button-primary-foreground-color-hover);
}
&:active {
background-color: var(--button-primary-background-color-active);
border-color: var(--button-primary-border-color-active);
color: var(--button-primary-foreground-color-active);
}
&[disabled],
&:disabled {
background-color: var(--button-background-color-disabled);
border-color: var(--button-border-color-disabled);
color: var(--button-foreground-color-disabled);
cursor: unset;
}
&.danger {
@extend %modal-danger-btn;
background-color: var(--modal-button-background-color-error);
border-color: var(--modal-button-background-color-error);
color: var(--modal-button-foreground-color-error);
}
}
.modal-scd-msg,
.modal-subtitle,
.modal-msg {
@include deprecated.body-small-typography;
color: var(--modal-text-foreground-color);
line-height: 1.5;
}
// TODO: Verify before removal. These selectors appear to be unused.
// .modal-scd-msg,
// .modal-subtitle,
// .modal-msg {
// ...
// }
.file-entry {
--file-entry-fg-color: var(--color-foreground-secondary);
display: flex;
.file-name {
@include deprecated.flex-row;
.file-icon {
@include deprecated.flex-center;
height: deprecated.$s-24;
width: deprecated.$s-16;
svg {
@extend %button-icon;
stroke: var(--icon-foreground);
}
&.icon-fill svg {
fill: var(--icon-foreground);
}
}
.file-name-edit {
@extend %input-element;
@include deprecated.body-small-typography;
flex-grow: 1;
}
.file-name-label {
@include deprecated.body-small-typography;
display: flex;
align-items: center;
gap: deprecated.$s-12;
flex-grow: 1;
.icon {
@include deprecated.flex-center;
height: deprecated.$s-16;
width: deprecated.$s-16;
svg {
@extend %button-icon-small;
stroke: var(--icon-foreground);
}
}
}
.edit-entry-buttons {
@include deprecated.flex-row;
button {
@extend %button-tertiary;
width: deprecated.$s-28;
height: deprecated.$s-32;
svg {
@extend %button-icon;
stroke: var(--icon-foreground);
}
}
}
}
flex-direction: column;
gap: var(--sp-m);
.error-message,
.progress-message {
display: flex;
align-items: center;
min-height: deprecated.$s-32;
color: var(--modal-text-foreground-color);
min-block-size: $sz-32;
color: var(--file-entry-fg-color);
}
.error-message {
@ -162,19 +244,26 @@
.linked-library {
display: flex;
align-items: center;
gap: deprecated.$s-12;
color: var(--modal-text-foreground-color);
gap: var(--sp-m);
color: var(--file-entry-fg-color);
.linked-library-tag {
@include deprecated.flex-center;
height: deprecated.$s-24;
width: deprecated.$s-24;
display: flex;
justify-content: center;
align-items: center;
block-size: $sz-24;
inline-size: $sz-24;
svg {
@extend %button-icon;
stroke: var(--icon-foreground);
display: flex;
justify-content: center;
align-items: center;
block-size: $sz-16;
inline-size: $sz-16;
color: transparent;
fill: none;
stroke-width: 1px;
stroke: var(--file-entry-fg-color);
}
&.error {
@ -185,71 +274,124 @@
}
}
&.loading {
.file-name {
color: var(--modal-text-foreground-color);
}
}
&.warning {
.file-name {
color: var(--element-foreground-warning);
.file-icon svg {
stroke: var(--element-foreground-warning);
}
.file-icon.icon-fill svg {
fill: var(--element-foreground-warning);
}
}
--file-entry-fg-color: var(--color-accent-warning);
}
&.success {
.file-name {
color: var(--modal-text-foreground-color);
.file-icon svg {
stroke: var(--modal-text-foreground-color);
}
.file-icon.icon-fill svg {
fill: var(--modal-text-foreground-color);
}
}
--file-entry-fg-color: var(--color-accent-sucess);
}
&.error {
.file-name {
color: var(--modal-text-foreground-color);
.file-icon svg {
stroke: var(--modal-text-foreground-color);
}
.file-icon.icon-fill svg {
fill: var(--modal-text-foreground-color);
}
}
--file-entry-fg-color: var(--color-accent-error);
}
&.editable {
.file-name {
color: var(--modal-text-foreground-color);
.file-icon svg {
stroke: var(--modal-text-foreground-color);
}
.file-icon.icon-fill svg {
fill: var(--modal-text-foreground-color);
}
}
--file-entry-fg-color: var(--color-foreground-primary);
}
}
.file-name {
display: flex;
align-items: center;
gap: var(--sp-l);
color: var(--file-entry-fg-color);
}
.edit-entry-buttons {
display: flex;
align-items: center;
gap: var(--sp-xs);
// button {
// display: flex;
// justify-content: center;
// align-items: center;
// border-radius: $br-8;
// background-color: transparent;
// border: $b-2 solid transparent;
// inline-size: $sz-28;
// block-size: $sz-32;
// cursor: pointer;
// color: var(--button-tertiary-foreground-color-rest);
// }
}
.file-name-edit {
display: flex;
align-items: center;
block-size: $sz-32;
border: $b-1 solid var(--color-background-tertiary);
color: var(--file-entry-fg-color);
flex-grow: 1;
position: relative;
border-radius: $br-4;
background-color: var(--color-background-tertiary);
}
.file-name-label {
display: flex;
align-items: center;
gap: var(--sp-m);
flex-grow: 1;
.icon {
display: flex;
justify-content: center;
align-items: center;
block-size: $sz-16;
inline-size: $sz-16;
color: var(--file-entry-fg-color);
}
}
.file-name-input {
@include use-typography("body-medium");
--edit-input-background-color: var(--color-background-tertiary);
--edit-input-border-color: transparent;
block-size: $sz-32;
inline-size: 100%;
padding: px2rem(6);
margin: 0;
border-radius: $br-8;
border: $b-1 solid var(--edit-input-border-color);
color: var(--color-foreground-primary);
background-color: var(--edit-input-background-color);
&:focus-visible {
--edit-input-background-color: var(--color-background-primary);
--edit-input-border-color: var(--color-accent-primary);
outline: none;
}
}
.file-icon,
.file-svg {
display: flex;
justify-content: center;
align-items: center;
block-size: $sz-24;
inline-size: $sz-16;
color: var(--file-entry-fg-color);
}
.file-svg {
fill: var(--file-entry-fg-color);
}
.context-notification-error {
--context-notification-bg-color: var(--modal-background-color);
--context-notification-bg-color: var(--color-background-primary);
}
.file-name-notification {
flex-grow: 1;
}
.import-error-disclaimer {
@ -266,10 +408,13 @@
}
.import-error-detail {
@include deprecated.body-small-typography;
margin-top: var(--sp-xs);
color: var(--modal-text-foreground-color);
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
margin-block-start: var(--sp-xs);
color: var(--color-foreground-secondary);
white-space: pre-wrap;
overflow-wrap: anywhere;
}
@ -277,64 +422,69 @@
.library-resolution {
display: flex;
flex-direction: column;
gap: deprecated.$s-12;
gap: var(--sp-m);
}
.library-resolution-message {
@include deprecated.body-small-typography;
color: var(--modal-text-foreground-color);
margin-bottom: deprecated.$s-8;
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
color: var(--color-foreground-secondary);
margin-block-end: var(--sp-s);
}
.library-resolution-item {
display: flex;
flex-direction: column;
gap: deprecated.$s-4;
padding: deprecated.$s-8 0;
gap: var(--sp-xs);
padding: var(--sp-s) 0;
}
.library-resolution-item-name {
@include deprecated.body-small-typography;
color: var(--modal-title-foreground-color);
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
line-height: 1.4;
color: var(--color-foreground-primary);
font-weight: 700;
}
.library-resolution-summary-file {
margin-bottom: deprecated.$s-16;
padding-bottom: deprecated.$s-12;
border-bottom: 1px solid var(--color-foreground-secondary);
margin-block-end: var(--sp-l);
padding-block-end: var(--sp-m);
border-bottom: $b-1 solid var(--color-foreground-secondary);
}
.library-resolution-linked {
color: var(--color-foreground-secondary);
font-size: deprecated.$fs-12;
font-size: px2rem(12);
}
.library-resolution-project {
color: var(--color-foreground-secondary);
font-size: deprecated.$fs-12;
margin-bottom: deprecated.$s-8;
font-size: px2rem(12);
margin-block-end: var(--sp-s);
}
// Summary file card
.summary-file {
display: flex;
flex-direction: column;
gap: deprecated.$s-8;
padding: deprecated.$s-12;
border: 1px solid var(--color-background-quaternary);
border-radius: deprecated.$br-8;
gap: var(--sp-s);
padding: var(--sp-m);
border: $b-1 solid var(--color-background-quaternary);
border-radius: $br-8;
background: var(--color-background-primary);
}
.summary-file-header {
display: flex;
align-items: center;
gap: deprecated.$s-8;
padding-bottom: deprecated.$s-8;
border-bottom: 1px solid var(--color-background-quaternary);
gap: var(--sp-s);
padding-block-end: var(--sp-s);
border-bottom: $b-1 solid var(--color-background-quaternary);
}
.summary-file-icon {
@ -343,9 +493,9 @@
}
.summary-file-name {
@include deprecated.body-medium-typography;
@include use-typography("body-medium");
color: var(--modal-title-foreground-color);
color: var(--color-foreground-primary);
font-weight: 700;
}
@ -353,15 +503,15 @@
.summary-section {
display: flex;
flex-direction: column;
gap: deprecated.$s-4;
padding-left: deprecated.$s-8;
gap: var(--sp-xs);
padding-inline-start: var(--sp-s);
}
.summary-section-header {
display: flex;
align-items: center;
gap: deprecated.$s-6;
padding: deprecated.$s-4 0;
gap: px2rem(6);
padding: var(--sp-xs) 0;
}
.summary-section-icon {
@ -372,7 +522,7 @@
.summary-list {
display: flex;
flex-direction: column;
gap: deprecated.$s-2;
gap: var(--sp-xxs);
list-style: none;
padding: 0;
margin: 0;
@ -382,9 +532,9 @@
display: flex;
align-items: center;
justify-content: space-between;
gap: deprecated.$s-8;
padding: deprecated.$s-4 deprecated.$s-8;
border-radius: deprecated.$br-4;
gap: var(--sp-s);
padding: var(--sp-xs) var(--sp-s);
border-radius: $br-4;
&:hover {
background: var(--color-background-secondary);
@ -392,26 +542,32 @@
}
.summary-item-name {
@include deprecated.body-small-typography;
color: var(--modal-title-foreground-color);
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
color: var(--color-foreground-primary);
flex: 1;
min-width: 0;
@include deprecated.text-ellipsis;
min-inline-size: 0;
display: block;
max-inline-size: 99%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// Auto-linked badge
.summary-linked-badge {
display: inline-flex;
align-items: center;
gap: deprecated.$s-4;
padding: deprecated.$s-2 deprecated.$s-8;
border-radius: deprecated.$br-12;
gap: var(--sp-xs);
padding: var(--sp-xxs) var(--sp-s);
border-radius: $br-12;
background: var(--color-accent-success-bg);
color: var(--color-accent-success);
font-size: deprecated.$fs-11;
font-weight: deprecated.$fw500;
font-size: px2rem(11);
font-weight: 500;
flex-shrink: 0;
}
@ -423,31 +579,38 @@
.summary-linked-info {
display: flex;
align-items: center;
gap: deprecated.$s-4;
gap: var(--sp-xs);
flex-shrink: 0;
}
.summary-linked-name {
@include deprecated.body-small-typography;
color: var(--modal-text-foreground-color);
font-weight: deprecated.$fw500;
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
line-height: 1.4;
color: var(--color-foreground-secondary);
font-weight: 500;
}
.summary-linked-project {
@include deprecated.body-small-typography;
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-weight: 400;
line-height: 1.4;
color: var(--color-foreground-secondary);
padding: deprecated.$s-2 deprecated.$s-8;
border-radius: deprecated.$br-12;
padding: var(--sp-xxs) var(--sp-s);
border-radius: $br-12;
background: var(--color-background-quaternary);
font-size: deprecated.$fs-11;
font-size: px2rem(11);
}
// No selection state
.summary-no-selection {
@include deprecated.body-small-typography;
// TODO: Typography does not match any existing DS typography token.
font-family: "worksans", "vazirmatn", sans-serif;
font-size: px2rem(12);
font-weight: 400;
line-height: 1.4;
color: var(--color-foreground-secondary);
font-style: italic;
flex-shrink: 0;

View File

@ -15,11 +15,12 @@
[app.main.store :as st]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.foundations.typography :as t]
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
[app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.ds.product.loader :refer [loader*]]
[app.main.ui.notifications.context-notification :refer [context-notification]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[beicon.v2.core :as rx]
@ -52,29 +53,27 @@
(mf/defc export-entry*
{::mf/private true}
[{:keys [file]}]
[:div {:class (stl/css-case
:file-entry true
:loading (:loading file)
:success (:export-success? file)
:error (:export-error? file))}
(let [level (cond
(:export-success? file) :success
(:export-error? file) :error
:else :info)]
[: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)}
(if (:loading file)
[:> loader* {:width 26
:title (tr "labels.loading")}]
(cond (:export-success? file)
[:> icon* {:icon-id i/tick
:class (stl/css :file-icon)
:size "s"}]
(:export-error? file)
[:> icon* {:icon-id i/close
:class (stl/css :file-icon)
:size "s"}]))
(if (:loading file)
[:div {:class (stl/css :file-name)}
[:> loader* {:width 26
:title (tr "labels.loading")}]
[:> text* {:class (stl/css :file-name-label)
:as "span"
:typography t/body-large}
(:name file)]]
[:> text* {:class (stl/css :file-name-label)
:as "span"
:typography t/body-large}
(:name file)]]])
[:> context-notification {:level level
:content (:name file)}])]))
(mf/defc export-dialog
{::mf/register modal/components