Merge pull request #3397 from penpot/juan-history-redesign

💄  History panel redesign
This commit is contained in:
Alejandro 2023-07-11 06:52:40 +02:00 committed by GitHub
commit b8dbd16b01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 314 additions and 44 deletions

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="M2.4 8a6 6 0 111.758 4.242M2.4 8l2.1-2M2.4 8L1 5.5m7.4-.7v3.6l2.4 1.2"/>
</svg>

After

Width:  |  Height:  |  Size: 201 B

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
<path d="m2 10 8-8m0 0H2m8 0v8"/> <path d="M4 12l8-8zm8-8H4zm0 0v8z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 156 B

View file

@ -8,6 +8,8 @@
.light, .light,
.default { .default {
--scrollbar-background-color: var(--color-foreground-secondary); --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-background-hover: var(--color-background-quaternary);
--button-foreground-hover: var(--color-accent-primary); --button-foreground-hover: var(--color-accent-primary);
@ -64,10 +66,9 @@
--tab-foreground-color-hover: var(--color-foreground-primary); --tab-foreground-color-hover: var(--color-foreground-primary);
--tab-foreground-color-selected: var(--color-accent-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: var(--color-foreground-secondary);
--title-foreground-color-hover: var(--color-foreground-primary); --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: var(--color-background-primary);
--layer-row-background-color-hover: var(--color-background-secondary); --layer-row-background-color-hover: var(--color-background-secondary);
@ -139,6 +140,7 @@
--color-bullet-border-color: var(--color-background-quaternary); --color-bullet-border-color: var(--color-background-quaternary);
--palette-handler-background-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: var(--color-background-tertiary);
--assets-item-background-color-hover: var(--color-background-quaternary); --assets-item-background-color-hover: var(--color-background-quaternary);
--assets-item-name-foreground-color: var(--color-foreground-secondary); --assets-item-name-foreground-color: var(--color-foreground-secondary);
@ -163,4 +165,14 @@
--not-found-background-color: var(--color-background-tertiary); --not-found-background-color: var(--color-background-tertiary);
--not-found-foreground-color: var(--color-foreground-secondary); --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);
} }

View file

@ -322,6 +322,7 @@
(def gutter-horizontal-refactor (icon-xref :gutter-horizontal-refactor)) (def gutter-horizontal-refactor (icon-xref :gutter-horizontal-refactor))
(def gutter-vertical-refactor (icon-xref :gutter-vertical-refactor)) (def gutter-vertical-refactor (icon-xref :gutter-vertical-refactor))
(def hide-refactor (icon-xref :hide-refactor)) (def hide-refactor (icon-xref :hide-refactor))
(def history-refactor (icon-xref :history-refactor))
(def img-refactor (icon-xref :img-refactor)) (def img-refactor (icon-xref :img-refactor))
(def icon-refactor (icon-xref :icon-refactor)) (def icon-refactor (icon-xref :icon-refactor))
(def justify-content-center-refactor (icon-xref :justify-content-center-refactor)) (def justify-content-center-refactor (icon-xref :justify-content-center-refactor))

View file

@ -17,7 +17,8 @@ $width-settings-bar-max: 500px;
max-width: 500px; max-width: 500px;
width: var(--width, $width-settings-bar); width: var(--width, $width-settings-bar);
height: 100%; height: 100%;
background-color: var(--color-background-primary); border-radius: $br-8;
background-color: var(--panel-background-color);
.resize-area { .resize-area {
position: absolute; position: absolute;

View file

@ -32,7 +32,7 @@
width: $s-28; width: $s-28;
border-radius: $br-8; border-radius: $br-8;
svg { svg {
@extend .button-icon-small; @extend .button-icon;
fill: var(--title-foreground-color-hover); fill: var(--title-foreground-color-hover);
} }
} }

View file

@ -5,11 +5,15 @@
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.history (ns app.main.ui.workspace.sidebar.history
(:require-macros [app.main.style :refer [css]])
(:require (:require
[app.common.data :as d] [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.data.workspace.common :as dwc]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [t] :as i18n] [app.util.i18n :refer [t] :as i18n]
@ -161,6 +165,23 @@
:image i/image :image i/image
i/layers)) 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] (defn is-shape? [type]
(contains? #{:shape :rect :circle :text :path :frame :group} type)) (contains? #{:shape :rect :circle :text :path :frame :group} type))
@ -180,7 +201,7 @@
(let [;; Group by id and type (let [;; Group by id and type
entries (->> candidates entries (->> candidates
(remove nil?) (remove nil?)
(group-by #(vector (:type %) (:operation %) (:id %)) )) (group-by #(vector (:type %) (:operation %) (:id %))))
single? (fn [coll] (= (count coll) 1)) single? (fn [coll] (= (count coll) 1))
@ -256,13 +277,37 @@
(mf/defc history-entry-details [{:keys [entry]}] (mf/defc history-entry-details [{:keys [entry]}]
(let [{entries :items} (mf/deref workspace-undo) (let [{entries :items} (mf/deref workspace-undo)
new-css-system (mf/use-ctx ctx/new-css-system)
objects (mf/deref refs/workspace-page-objects)] objects (mf/deref refs/workspace-page-objects)]
[:div.history-entry-detail (if new-css-system
[:div {:class (css :history-entry-detail)}
(case (:operation entry) (case (:operation entry)
:new :new
(:name (get-object (:detail entry) entries objects)) (: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 :delete
[:ul.history-entry-details-list [:ul.history-entry-details-list
(for [id (:detail entry)] (for [id (:detail entry)]
@ -278,47 +323,98 @@
[:div shape-name] [:div shape-name]
[:div (str/join ", " attributes)]]))] [:div (str/join ", " attributes)]]))]
nil)])) nil)]
)))
(mf/defc history-entry [{:keys [locale entry idx-entry disabled? current?]}] (mf/defc history-entry [{:keys [locale entry idx-entry disabled? current?]}]
(let [hover? (mf/use-state false) (let [hover? (mf/use-state false)
show-detail? (mf/use-state false)] new-css-system (mf/use-ctx ctx/new-css-system)
[:div.history-entry {:class (dom/classnames show-detail? (mf/use-state false)]
:disabled disabled? (if new-css-system
:current current? [:div {:class (dom/classnames (css :history-entry) true
:hover @hover? (css :disabled) disabled?
:show-detail @show-detail?) (css :current) current?
:on-pointer-enter #(reset! hover? true) (css :hover) @hover?
:on-pointer-leave #(reset! hover? false) (css :show-detail) @show-detail?)
:on-click #(st/emit! (dwc/undo-to-index idx-entry))} :on-pointer-enter #(reset! hover? true)
[:div.history-entry-summary :on-pointer-leave #(reset! hover? false)
[:div.history-entry-summary-icon (entry->icon entry)] :on-click #(st/emit! (dwc/undo-to-index idx-entry))}
[:div.history-entry-summary-text (entry->message locale entry)] [:div {:class (dom/classnames (css :history-entry-summary) true)}
(when (:detail entry) [:div {:class (dom/classnames (css :history-entry-summary-icon) true)} (entry->icon-refactor entry)]
[:div.history-entry-summary-button {:on-click #(when (:detail entry) [:div {:class (dom/classnames (css :history-entry-summary-text) true)} (entry->message locale entry)]
(swap! show-detail? not))} (when (:detail entry)
i/arrow-slide])] [: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? (when @show-detail?
[:& history-entry-details {:entry entry}])])) [:& 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 [] (mf/defc history-toolbox []
(let [locale (mf/deref i18n/locale) (let [locale (mf/deref i18n/locale)
new-css-system (mf/use-ctx ctx/new-css-system)
objects (mf/deref refs/workspace-page-objects) objects (mf/deref refs/workspace-page-objects)
{:keys [items index]} (mf/deref workspace-undo) {:keys [items index]} (mf/deref workspace-undo)
entries (parse-entries items objects)] entries (parse-entries items objects)
[:div.history-toolbox toggle-history
[:div.history-toolbox-title (t locale "workspace.undo.title")] (mf/use-fn
(if (empty? entries) #(st/emit! (-> (dw/toggle-layout-flag :document-history)
[:div.history-entry-empty (vary-meta assoc ::ev/origin "history-toolbox"))))]
[:div.history-entry-empty-icon i/recent] (if new-css-system
[:div.history-entry-empty-msg (t locale "workspace.undo.empty")]] [:div {:class (css :history-toolbox)}
[:ul.history-entries [:div {:class (css :history-toolbox-title)}
(for [[idx-entry entry] (->> entries (map-indexed vector) reverse)] #_[i (range 0 10)] [:span (t locale "workspace.undo.title")]
[:& history-entry {:key (str "entry-" idx-entry) [:div {:class (css :close-button)
:locale locale :on-click toggle-history}
:entry entry i/close-refactor]]
:idx-entry idx-entry (if (empty? entries)
:current? (= idx-entry index) [:div {:class (css :history-entry-empty)}
:disabled? (> idx-entry index)}])])])) [: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)}])])])))

View file

@ -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"}

View file

@ -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;
}
}
}
}
}

View file

@ -107,7 +107,7 @@
.advanced-options-wrapper { .advanced-options-wrapper {
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: var(--title-background-color); background-color: var(--assets-title-background-color);
.typography-options { .typography-options {
position: relative; position: relative;

View file

@ -15,7 +15,7 @@
padding: $s-2 $s-2 $s-2 0; padding: $s-2 $s-2 $s-2 0;
margin: $s-4 $s-4 0 $s-4; margin: $s-4 $s-4 0 $s-4;
border-radius: $br-6; border-radius: $br-6;
background-color: var(--title-background-color); background-color: var(--panel-title-background-color);
.shortcuts-title { .shortcuts-title {
@include flexCenter; @include flexCenter;
@ -31,6 +31,7 @@
height: $s-28; height: $s-28;
width: $s-28; width: $s-28;
border-radius: $br-5; border-radius: $br-5;
svg { svg {
@extend .button-icon; @extend .button-icon;
} }