diff --git a/frontend/resources/images/icons/history-refactor.svg b/frontend/resources/images/icons/history-refactor.svg
new file mode 100644
index 0000000000..58a542c26d
--- /dev/null
+++ b/frontend/resources/images/icons/history-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/open-link-refactor.svg b/frontend/resources/images/icons/open-link-refactor.svg
index be28efba26..c3bcd5df1e 100644
--- a/frontend/resources/images/icons/open-link-refactor.svg
+++ b/frontend/resources/images/icons/open-link-refactor.svg
@@ -1,3 +1,3 @@
diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss
index 58f303bf2d..585181d914 100644
--- a/frontend/resources/styles/common/refactor/design-tokens.scss
+++ b/frontend/resources/styles/common/refactor/design-tokens.scss
@@ -8,6 +8,8 @@
.light,
.default {
--scrollbar-background-color: var(--color-foreground-secondary);
+ --panel-background-color: var(--color-background-primary);
+ --panel-title-background-color: var(--color-background-secondary);
--button-background-hover: var(--color-background-quaternary);
--button-foreground-hover: var(--color-accent-primary);
@@ -64,10 +66,9 @@
--tab-foreground-color-hover: var(--color-foreground-primary);
--tab-foreground-color-selected: var(--color-accent-primary);
- --title-background-color: var(--color-background-secondary);
+ --title-background-color: var(--color-background-primary);
--title-foreground-color: var(--color-foreground-secondary);
--title-foreground-color-hover: var(--color-foreground-primary);
- --title-background-color: var(--color-background-primary);
--layer-row-background-color: var(--color-background-primary);
--layer-row-background-color-hover: var(--color-background-secondary);
@@ -139,6 +140,7 @@
--color-bullet-border-color: var(--color-background-quaternary);
--palette-handler-background-color: var(--color-background-quaternary);
+ --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);
--assets-item-name-foreground-color: var(--color-foreground-secondary);
@@ -163,4 +165,14 @@
--not-found-background-color: var(--color-background-tertiary);
--not-found-foreground-color: var(--color-foreground-secondary);
+
+ --entry-foreground-color: var(--color-foreground-secondary);
+ --entry-background-color: var(--color-background-tertiary);
+ --entry-background-color-disabled: var(--color-background-primary);
+ --entry-border-color-disabled: var(--color-background-quaternary);
+ --entry-foreground-color-hover: var(--color-foreground-primary);
+ --entry-background-color-hover: var(--color-background-quaternary);
+
+ --empty-message-background-color: var(--color-background-tertiary);
+ --empty-message-foreground-color: var(--color-foreground-secondary);
}
diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs
index 725ba7063a..c435ef76d2 100644
--- a/frontend/src/app/main/ui/icons.cljs
+++ b/frontend/src/app/main/ui/icons.cljs
@@ -322,6 +322,7 @@
(def gutter-horizontal-refactor (icon-xref :gutter-horizontal-refactor))
(def gutter-vertical-refactor (icon-xref :gutter-vertical-refactor))
(def hide-refactor (icon-xref :hide-refactor))
+(def history-refactor (icon-xref :history-refactor))
(def img-refactor (icon-xref :img-refactor))
(def icon-refactor (icon-xref :icon-refactor))
(def justify-content-center-refactor (icon-xref :justify-content-center-refactor))
diff --git a/frontend/src/app/main/ui/workspace/sidebar.scss b/frontend/src/app/main/ui/workspace/sidebar.scss
index 3e3a869def..c12f02ab67 100644
--- a/frontend/src/app/main/ui/workspace/sidebar.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar.scss
@@ -17,7 +17,8 @@ $width-settings-bar-max: 500px;
max-width: 500px;
width: var(--width, $width-settings-bar);
height: 100%;
- background-color: var(--color-background-primary);
+ border-radius: $br-8;
+ background-color: var(--panel-background-color);
.resize-area {
position: absolute;
diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.scss b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.scss
index a425a1117f..92272b96a3 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.scss
@@ -32,7 +32,7 @@
width: $s-28;
border-radius: $br-8;
svg {
- @extend .button-icon-small;
+ @extend .button-icon;
fill: var(--title-foreground-color-hover);
}
}
diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.cljs b/frontend/src/app/main/ui/workspace/sidebar/history.cljs
index 908491bf5a..67cb6075d8 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/history.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/history.cljs
@@ -5,11 +5,15 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.history
+ (:require-macros [app.main.style :refer [css]])
(:require
[app.common.data :as d]
+ [app.main.data.events :as ev]
+ [app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
[app.main.refs :as refs]
[app.main.store :as st]
+ [app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :refer [t] :as i18n]
@@ -161,6 +165,23 @@
:image i/image
i/layers))
+(defn entry->icon-refactor [{:keys [type]}]
+ (case type
+ :page i/document-refactor
+ :shape i/svg-refactor
+ :rect i/rectangle-refactor
+ :circle i/elipse-refactor
+ :text i/text-refactor
+ :path i/path-refactor
+ :frame i/board-refactor
+ :group i/group-refactor
+ :color i/drop-refactor
+ :typography i/text-palette-refactor
+ :component i/component-refactor
+ :media i/img-refactor
+ :image i/img-refactor
+ i/svg-refactor))
+
(defn is-shape? [type]
(contains? #{:shape :rect :circle :text :path :frame :group} type))
@@ -180,7 +201,7 @@
(let [;; Group by id and type
entries (->> candidates
(remove nil?)
- (group-by #(vector (:type %) (:operation %) (:id %)) ))
+ (group-by #(vector (:type %) (:operation %) (:id %))))
single? (fn [coll] (= (count coll) 1))
@@ -256,13 +277,37 @@
(mf/defc history-entry-details [{:keys [entry]}]
(let [{entries :items} (mf/deref workspace-undo)
+ new-css-system (mf/use-ctx ctx/new-css-system)
objects (mf/deref refs/workspace-page-objects)]
- [:div.history-entry-detail
+ (if new-css-system
+ [:div {:class (css :history-entry-detail)}
(case (:operation entry)
:new
(:name (get-object (:detail entry) entries objects))
+ :delete
+ [:ul {:class (css :ul.history-entry-details-list)}
+ (for [id (:detail entry)]
+ (let [shape-name (:name (get-object id entries objects))]
+ [:li {:key id} shape-name]))]
+
+
+ :modify
+ [:ul {:class (css :ul.history-entry-details-list)}
+ (for [[id attributes] (:detail entry)]
+ (let [shape-name (:name (get-object id entries objects))]
+ [:li {:key id}
+ [:div shape-name]
+ [:div (str/join ", " attributes)]]))]
+
+ nil)]
+
+ [:div.history-entry-detail
+ (case (:operation entry)
+ :new
+ (:name (get-object (:detail entry) entries objects))
+
:delete
[:ul.history-entry-details-list
(for [id (:detail entry)]
@@ -278,47 +323,98 @@
[:div shape-name]
[:div (str/join ", " attributes)]]))]
- nil)]))
+ nil)]
+ )))
(mf/defc history-entry [{:keys [locale entry idx-entry disabled? current?]}]
- (let [hover? (mf/use-state false)
- show-detail? (mf/use-state false)]
- [:div.history-entry {:class (dom/classnames
- :disabled disabled?
- :current current?
- :hover @hover?
- :show-detail @show-detail?)
- :on-pointer-enter #(reset! hover? true)
- :on-pointer-leave #(reset! hover? false)
- :on-click #(st/emit! (dwc/undo-to-index idx-entry))}
- [:div.history-entry-summary
- [:div.history-entry-summary-icon (entry->icon entry)]
- [:div.history-entry-summary-text (entry->message locale entry)]
- (when (:detail entry)
- [:div.history-entry-summary-button {:on-click #(when (:detail entry)
- (swap! show-detail? not))}
- i/arrow-slide])]
+ (let [hover? (mf/use-state false)
+ new-css-system (mf/use-ctx ctx/new-css-system)
+ show-detail? (mf/use-state false)]
+ (if new-css-system
+ [:div {:class (dom/classnames (css :history-entry) true
+ (css :disabled) disabled?
+ (css :current) current?
+ (css :hover) @hover?
+ (css :show-detail) @show-detail?)
+ :on-pointer-enter #(reset! hover? true)
+ :on-pointer-leave #(reset! hover? false)
+ :on-click #(st/emit! (dwc/undo-to-index idx-entry))}
+ [:div {:class (dom/classnames (css :history-entry-summary) true)}
+ [:div {:class (dom/classnames (css :history-entry-summary-icon) true)} (entry->icon-refactor entry)]
+ [:div {:class (dom/classnames (css :history-entry-summary-text) true)} (entry->message locale entry)]
+ (when (:detail entry)
+ [:div {:class (dom/classnames (css :history-entry-summary-button) true
+ (css :button-opened) @show-detail?)
+ :on-click #(when (:detail entry)
+ (swap! show-detail? not))}
+ i/arrow-refactor])]
- (when show-detail?
- [:& history-entry-details {:entry entry}])]))
+ (when @show-detail?
+ [:& history-entry-details {:entry entry}])]
+
+ [:div.history-entry {:class (dom/classnames
+ :disabled disabled?
+ :current current?
+ :hover @hover?
+ :show-detail @show-detail?)
+ :on-pointer-enter #(reset! hover? true)
+ :on-pointer-leave #(reset! hover? false)
+ :on-click #(st/emit! (dwc/undo-to-index idx-entry))}
+ [:div.history-entry-summary
+ [:div.history-entry-summary-icon (entry->icon entry)]
+ [:div.history-entry-summary-text (entry->message locale entry)]
+ (when (:detail entry)
+ [:div.history-entry-summary-button {:on-click #(when (:detail entry)
+ (swap! show-detail? not))}
+ i/arrow-slide])]
+
+ (when show-detail?
+ [:& history-entry-details {:entry entry}])])))
(mf/defc history-toolbox []
(let [locale (mf/deref i18n/locale)
+ new-css-system (mf/use-ctx ctx/new-css-system)
objects (mf/deref refs/workspace-page-objects)
{:keys [items index]} (mf/deref workspace-undo)
- entries (parse-entries items objects)]
- [:div.history-toolbox
- [:div.history-toolbox-title (t locale "workspace.undo.title")]
- (if (empty? entries)
- [:div.history-entry-empty
- [:div.history-entry-empty-icon i/recent]
- [:div.history-entry-empty-msg (t locale "workspace.undo.empty")]]
- [:ul.history-entries
- (for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
- [:& history-entry {:key (str "entry-" idx-entry)
- :locale locale
- :entry entry
- :idx-entry idx-entry
- :current? (= idx-entry index)
- :disabled? (> idx-entry index)}])])]))
+ entries (parse-entries items objects)
+ toggle-history
+ (mf/use-fn
+ #(st/emit! (-> (dw/toggle-layout-flag :document-history)
+ (vary-meta assoc ::ev/origin "history-toolbox"))))]
+ (if new-css-system
+ [:div {:class (css :history-toolbox)}
+ [:div {:class (css :history-toolbox-title)}
+ [:span (t locale "workspace.undo.title")]
+ [:div {:class (css :close-button)
+ :on-click toggle-history}
+ i/close-refactor]]
+ (if (empty? entries)
+ [:div {:class (css :history-entry-empty)}
+ [:div {:class (css :history-entry-empty-icon)} i/history-refactor]
+ [:div {:class (css :history-entry-empty-msg)} (t locale "workspace.undo.empty")]]
+ [:ul {:class (css :history-entries)}
+ (for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
+ [:& history-entry {:key (str "entry-" idx-entry)
+ :locale locale
+ :entry entry
+ :idx-entry idx-entry
+ :current? (= idx-entry index)
+ :disabled? (> idx-entry index)}])])]
+
+ [:div.history-toolbox
+ [:div.history-toolbox-title (t locale "workspace.undo.title")]
+ (if (empty? entries)
+ [:div.history-entry-empty
+ [:div.history-entry-empty-icon i/recent]
+ [:div.history-entry-empty-msg (t locale "workspace.undo.empty")]]
+ [:ul.history-entries
+ (for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)]
+ [:& history-entry {:key (str "entry-" idx-entry)
+ :locale locale
+ :entry entry
+ :idx-entry idx-entry
+ :current? (= idx-entry index)
+ :disabled? (> idx-entry index)}])])])))
+
+
diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.css.json b/frontend/src/app/main/ui/workspace/sidebar/history.css.json
new file mode 100644
index 0000000000..2bbdba20b9
--- /dev/null
+++ b/frontend/src/app/main/ui/workspace/sidebar/history.css.json
@@ -0,0 +1 @@
+{"button-primary":"sidebar_history_button-primary_3QHPC","button-secondary":"sidebar_history_button-secondary_-f-3z","button-tertiary":"sidebar_history_button-tertiary_IzuLu","history-toolbox":"sidebar_history_history-toolbox_-jdvy","history-toolbox-title":"sidebar_history_history-toolbox-title_9pxvS","close-button":"sidebar_history_close-button_CmY2q","button-tag":"sidebar_history_button-tag_9aylo","button-icon":"sidebar_history_button-icon_UeFr2","history-entry-empty":"sidebar_history_history-entry-empty_SINxx","history-entry-empty-icon":"sidebar_history_history-entry-empty-icon_XJdB6","button-icon-small":"sidebar_history_button-icon-small_9M0oh","history-entries":"sidebar_history_history-entries_NgKRp","history-entry":"sidebar_history_history-entry_lGPio","history-entry-summary":"sidebar_history_history-entry-summary_S3Glf","history-entry-summary-button":"sidebar_history_history-entry-summary-button_AjNW8","history-entry-summary-icon":"sidebar_history_history-entry-summary-icon_F-iya","asset-element":"sidebar_history_asset-element_Lm478","new-scrollbar":"sidebar_history_new-scrollbar_lmxNu","history-entry-empty-msg":"sidebar_history_history-entry-empty-msg_S3wX7","disabled":"sidebar_history_disabled_u0U-e","hover":"sidebar_history_hover_RnLwu","button-opened":"sidebar_history_button-opened_PdprO","history-entry-summary-text":"sidebar_history_history-entry-summary-text_bBYso","history-entry-detail":"sidebar_history_history-entry-detail_-QXf6","history-entry-details-list":"sidebar_history_history-entry-details-list_shkso"}
\ No newline at end of file
diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.scss b/frontend/src/app/main/ui/workspace/sidebar/history.scss
new file mode 100644
index 0000000000..87adac9c92
--- /dev/null
+++ b/frontend/src/app/main/ui/workspace/sidebar/history.scss
@@ -0,0 +1,155 @@
+// 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";
+
+.history-toolbox {
+ display: flex;
+ flex-direction: column;
+ background-color: var(--panel-background-color);
+
+ .history-toolbox-title {
+ @include flexCenter;
+ @include tabTitleTipography;
+ position: relative;
+ height: $s-32;
+ min-height: $s-32;
+ margin: $s-4 $s-4 0 $s-4;
+ border-radius: $br-8;
+ background-color: var(--panel-title-background-color);
+
+ span {
+ @include flexCenter;
+ flex-grow: 1;
+ color: var(--title-foreground-color-hover);
+ }
+
+ .close-button {
+ @extend .button-tertiary;
+ position: absolute;
+ right: $s-2;
+ top: $s-2;
+ height: $s-28;
+ width: $s-28;
+ border-radius: $br-6;
+ svg {
+ @extend .button-icon;
+ }
+ }
+ }
+
+ .history-entry-empty {
+ @include flexCenter;
+ flex-direction: column;
+ gap: $s-16;
+ padding: $s-28 $s-16;
+ text-align: center;
+
+ .history-entry-empty-icon {
+ @include flexCenter;
+ height: $s-48;
+ width: $s-48;
+ border-radius: 50%;
+ background-color: var(--empty-message-background-color);
+ svg {
+ @extend .button-icon;
+ height: $s-28;
+ width: $s-28;
+ margin-left: calc(-1 * $s-2);
+ stroke: var(--empty-message-foreground-color);
+ }
+ }
+
+ .history-entry-empty-msg {
+ @include titleTipography;
+ color: var(--title-foreground-secondary);
+ }
+ }
+
+ ul.history-entries {
+ height: 100%;
+ padding: $s-12;
+ overflow-x: hidden;
+ overflow-y: auto;
+ font-size: $fs-12;
+
+ .history-entry {
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ min-height: $s-32;
+ margin: $s-4;
+ padding: $s-4 $s-8;
+ border: $s-2 solid transparent;
+ border-radius: $s-8;
+ background-color: var(--entry-background-color);
+ cursor: pointer;
+ transition: border 0.2s;
+
+ &.disabled {
+ border-color: var(--entry-border-color-disabled);
+ background-color: var(--entry-background-color-disabled);
+ }
+
+ &.hover,
+ &:hover {
+ background-color: var(--entry-background-color-hover);
+ color: var(--entry-foreground-color-hover);
+ .history-entry-summary {
+ .history-entry-summary-icon {
+ svg {
+ stroke: var(--entry-foreground-color-hover);
+ }
+ }
+ .history-entry-summary-button {
+ opacity: $op-10;
+ &.button-opened {
+ svg {
+ transform: rotate(90deg);
+ }
+ }
+ }
+ }
+ }
+
+ .history-entry-summary {
+ display: flex;
+ align-items: center;
+ .history-entry-summary-icon {
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--entry-foreground-color);
+ }
+ }
+ .history-entry-summary-text {
+ margin: 0 $s-8;
+ }
+ .history-entry-summary-button {
+ opacity: $op-0;
+ margin-left: auto;
+ &.button-opened {
+ svg {
+ transform: rotate(90deg);
+ }
+ }
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--entry-foreground-color);
+ }
+ }
+ }
+
+ .history-entry-detail {
+ display: block;
+ padding-top: $s-16;
+
+ ul.history-entry-details-list {
+ margin: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss
index 0763cbf918..6f0d48a2af 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss
@@ -107,7 +107,7 @@
.advanced-options-wrapper {
height: 100%;
width: 100%;
- background-color: var(--title-background-color);
+ background-color: var(--assets-title-background-color);
.typography-options {
position: relative;
diff --git a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss
index e8527b9c66..d58f12e1b8 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss
@@ -15,7 +15,7 @@
padding: $s-2 $s-2 $s-2 0;
margin: $s-4 $s-4 0 $s-4;
border-radius: $br-6;
- background-color: var(--title-background-color);
+ background-color: var(--panel-title-background-color);
.shortcuts-title {
@include flexCenter;
@@ -31,6 +31,7 @@
height: $s-28;
width: $s-28;
border-radius: $br-5;
+
svg {
@extend .button-icon;
}