From cbb3f6672f5a0874adaa1592ff7bc6c09e3b2ea8 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Fri, 28 Mar 2025 10:38:35 +0100 Subject: [PATCH 01/10] :bug: Fix asset name on inspect tab (#6173) Signed-off-by: Eva Marco --- CHANGES.md | 2 + backend/src/app/rpc/commands/viewer.clj | 5 +- frontend/playwright/ui/pages/WorkspacePage.js | 3 ++ .../ui/specs/inspect-layout.spec.js | 52 +++++++++++++++++++ frontend/src/app/main/data/viewer.cljs | 2 + .../main/ui/inspect/attributes/common.cljs | 23 ++++---- 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7b2016eec..27f46b4b4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -40,6 +40,8 @@ - Fix problem with constraints when creating group [Taiga #10455](https://tree.taiga.io/project/penpot/issue/10455) - Fix opening pen with shortcut multiple times breaks toolbar [Taiga #10566](https://tree.taiga.io/project/penpot/issue/10566) - Fix actions when workspace is visited first time [Taiga #10548](https://tree.taiga.io/project/penpot/issue/10548) +- Chat icon overlaps "Show" button in carrousel section [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) +- Fix assets name on inspect tab [Taiga #10630](https://tree.taiga.io/project/penpot/issue/10630) - Fix chat icon overlaps "Show" button in carrousel section [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) - Fix incorrect handling of background task result (now task rows are properly marked as completed) diff --git a/backend/src/app/rpc/commands/viewer.clj b/backend/src/app/rpc/commands/viewer.clj index 7e471e4fc..e86f13033 100644 --- a/backend/src/app/rpc/commands/viewer.clj +++ b/backend/src/app/rpc/commands/viewer.clj @@ -78,7 +78,10 @@ :always (update :data select-keys [:id :options :pages :pages-index :components])) - libs (files/get-file-libraries conn file-id) + libs (->> (files/get-file-libraries conn file-id) + (mapv (fn [{:keys [id] :as lib}] + (merge lib (files/get-file cfg id))))) + links (->> (db/query conn :share-link {:file-id file-id}) (mapv (fn [row] (-> row diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index 96646a157..3fc9b42db 100644 --- a/frontend/playwright/ui/pages/WorkspacePage.js +++ b/frontend/playwright/ui/pages/WorkspacePage.js @@ -245,6 +245,9 @@ export class WorkspacePage extends BaseWebSocketPage { async clickAssets(clickOptions = {}) { await this.sidebar.getByText("Assets").click(clickOptions); } + async clickLayers(clickOptions = {}) { + await this.sidebar.getByText("Layers").click(clickOptions); + } async openLibrariesModal(clickOptions = {}) { await this.sidebar.getByTestId("libraries").click(clickOptions); diff --git a/frontend/playwright/ui/specs/inspect-layout.spec.js b/frontend/playwright/ui/specs/inspect-layout.spec.js index c5678ae01..176992ca3 100644 --- a/frontend/playwright/ui/specs/inspect-layout.spec.js +++ b/frontend/playwright/ui/specs/inspect-layout.spec.js @@ -70,3 +70,55 @@ test("[Taiga #9116] Copy CSS background color in the selected format in the INSP ); expect(rgbaColorText).toContain("background: rgba("); }); + +test("[Taiga #10630] [INSPECT] Style assets not being displayed on info tab", async ({ + page, + context, +}) => { + const workspacePage = new WorkspacePage(page); + await workspacePage.setupEmptyFile(page); + await workspacePage.goToWorkspace(); + await workspacePage.mockRPC( + "link-file-to-library", + "workspace/link-file-to-library.json", + ); + + await workspacePage.mockRPC( + "unlink-file-from-library", + "workspace/unlink-file-from-library.json", + ); + + await workspacePage.mockRPC( + "get-team-shared-files?team-id=*", + "workspace/get-team-shared-libraries-non-empty.json", + ); + + await workspacePage.clickColorPalette(); + await workspacePage.clickAssets(); + await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-library.json"); + await workspacePage.openLibrariesModal(); + await workspacePage.clickLibrary("Testing library 1"); + await workspacePage.closeLibrariesModal(); + + await expect( + workspacePage.palette.getByRole("button", { name: "test-color-187cd5" }), + ).toBeVisible(); + + await workspacePage.clickLayers(); + + await workspacePage.rectShapeButton.click(); + await workspacePage.clickWithDragViewportAt(128, 128, 200, 100); + await workspacePage.clickLeafLayer("Rectangle"); + await workspacePage.palette + .getByRole("button", { name: "test-color-187cd5" }) + .click(); + + const inspectButton = workspacePage.page.getByRole("tab", { + name: "Inspect", + }); + await inspectButton.click(); + + const colorLibraryName = workspacePage.page.getByTestId("color-library-name"); + + await expect(colorLibraryName).toHaveText("test-color-187cd5"); +}); diff --git a/frontend/src/app/main/data/viewer.cljs b/frontend/src/app/main/data/viewer.cljs index 770c24bf1..d3baca131 100644 --- a/frontend/src/app/main/data/viewer.cljs +++ b/frontend/src/app/main/data/viewer.cljs @@ -189,6 +189,8 @@ (assoc :share-links share-links) (assoc :current-team-id team-id) (assoc :teams {team-id team}) + (assoc :files (-> (d/index-by :id libraries) + (assoc (:id file) file))) (assoc :viewer {:libraries (d/index-by :id libraries) :users (d/index-by :id users) :permissions permissions diff --git a/frontend/src/app/main/ui/inspect/attributes/common.cljs b/frontend/src/app/main/ui/inspect/attributes/common.cljs index b9ab29bd7..1a0f16d2c 100644 --- a/frontend/src/app/main/ui/inspect/attributes/common.cljs +++ b/frontend/src/app/main/ui/inspect/attributes/common.cljs @@ -32,16 +32,11 @@ (get-in state [libraries-place file-id :data :colors]))] (l/derived get-library st/state))) -(defn- get-colors-library [color] - (let [colors-library-v (-> (mf/use-memo - (mf/deps (:file-id color)) - #(make-colors-library-ref :viewer-libraries (:file-id color))) - mf/deref) - colors-library-ws (-> (mf/use-memo - (mf/deps (:file-id color)) - #(make-colors-library-ref :libraries (:file-id color))) - mf/deref)] - (or colors-library-v colors-library-ws))) +(defn- use-colors-library [color] + (-> (mf/use-memo + (mf/deps (:file-id color)) + #(make-colors-library-ref :files (:file-id color))) + mf/deref)) (defn- get-file-colors [] (or (mf/deref file-colors-ref) (mf/deref refs/workspace-file-colors))) @@ -54,7 +49,7 @@ (str/capital $))) (mf/defc color-row [{:keys [color format copy-data on-change-format]}] - (let [colors-library (get-colors-library color) + (let [colors-library (use-colors-library color) file-colors (get-file-colors) color-library-name (get-in (or colors-library file-colors) [(:id color) :name]) color (assoc color :color-library-name color-library-name) @@ -85,7 +80,8 @@ (when color-library-name [:div {:class (stl/css :second-row)} - [:div {:class (stl/css :color-name-library)} + [:div {:class (stl/css :color-name-library) + :data-testid "color-library-name"} color-library-name]])]] [:div {:class (stl/css :image-download)} @@ -146,6 +142,7 @@ (when color-library-name [:div {:class (stl/css :second-row)} - [:div {:class (stl/css :color-name-library)} + [:div {:class (stl/css :color-name-library) + :data-testid "color-library-name"} color-library-name]])]]))) From c1853a71a93872ab01b0278930f5093eafd03697 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Fri, 28 Mar 2025 13:15:35 +0100 Subject: [PATCH 02/10] :bug: Fix available resize area (#6186) --- CHANGES.md | 1 + frontend/src/app/main/ui/workspace/sidebar.cljs | 4 +++- frontend/src/app/main/ui/workspace/sidebar.scss | 6 ++++++ frontend/src/app/main/ui/workspace/tokens/sidebar.cljs | 3 ++- frontend/src/app/main/ui/workspace/tokens/sidebar.scss | 6 ++++++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 27f46b4b4..cd2b71aa5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -44,6 +44,7 @@ - Fix assets name on inspect tab [Taiga #10630](https://tree.taiga.io/project/penpot/issue/10630) - Fix chat icon overlaps "Show" button in carrousel section [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) - Fix incorrect handling of background task result (now task rows are properly marked as completed) +- Fix available size of resize handler [Taiga #10639](https://tree.taiga.io/project/penpot/issue/10639) ## 2.5.4 diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index a0bc9f27d..95f445be1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -110,7 +110,9 @@ [:div {:class (stl/css :resize-area-horiz) :on-pointer-down on-pointer-down-pages :on-lost-pointer-capture on-lost-pointer-capture-pages - :on-pointer-move on-pointer-move-pages}]) + :on-pointer-move on-pointer-move-pages} + + [:div {:class (stl/css :resize-handle-horiz)}]]) [:& layers-toolbox {:size-parent size :size size-pages}]]) diff --git a/frontend/src/app/main/ui/workspace/sidebar.scss b/frontend/src/app/main/ui/workspace/sidebar.scss index 2d1cb7e5f..3101f9d8c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/sidebar.scss @@ -88,6 +88,12 @@ $width-settings-bar-max: $s-500; position: absolute; left: 0; width: 100%; + padding: $s-3 0 $s-1 0; + height: $s-6; + cursor: ns-resize; +} + +.resize-handle-horiz { border-bottom: $s-2 solid var(--resize-area-border-color); cursor: ns-resize; } diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 2fe682fb3..e4b596a4e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -439,6 +439,7 @@ [:div {:class (stl/css :resize-area-horiz) :on-pointer-down on-pointer-down-pages :on-lost-pointer-capture on-lost-pointer-capture-pages - :on-pointer-move on-pointer-move-pages}] + :on-pointer-move on-pointer-move-pages} + [:div {:class (stl/css :resize-handle-horiz)}]] [:> tokens-section* {:tokens-lib tokens-lib}]] [:> import-export-button*]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss index 01a8d245c..70d9584a6 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss @@ -170,6 +170,12 @@ position: absolute; left: 0; width: 100%; + padding: $s-3 0 $s-1 0; + height: $s-6; + cursor: ns-resize; +} + +.resize-handle-horiz { border-bottom: $s-2 solid var(--resize-area-border-color); cursor: ns-resize; } From b1df0ac194bf36ed57a1bbc729ec2a2a4a6911eb Mon Sep 17 00:00:00 2001 From: Xavier Julian Date: Wed, 26 Mar 2025 14:02:50 +0100 Subject: [PATCH 03/10] :sparkles: Add a default 256 maxlength value to all input fields --- frontend/src/app/main/constants.cljs | 2 ++ frontend/src/app/main/ui/ds/controls/combobox.cljs | 5 ++++- frontend/src/app/main/ui/ds/controls/input.cljs | 5 ++++- .../workspace/tokens/components/controls/input_tokens.cljs | 6 +++++- .../src/app/main/ui/workspace/tokens/modals/themes.cljs | 1 + frontend/src/app/main/ui/workspace/tokens/sets.cljs | 1 + frontend/src/app/main/ui/workspace/tokens/sidebar.scss | 5 +++++ 7 files changed, 22 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/constants.cljs b/frontend/src/app/main/constants.cljs index 31bd4dfd6..e9d3137c4 100644 --- a/frontend/src/app/main/constants.cljs +++ b/frontend/src/app/main/constants.cljs @@ -192,3 +192,5 @@ :height 720}]) (def zoom-half-pixel-precision 8) + +(def max-input-length 255) diff --git a/frontend/src/app/main/ui/ds/controls/combobox.cljs b/frontend/src/app/main/ui/ds/controls/combobox.cljs index 8e3ceba5c..04a16ace0 100644 --- a/frontend/src/app/main/ui/ds/controls/combobox.cljs +++ b/frontend/src/app/main/ui/ds/controls/combobox.cljs @@ -10,6 +10,7 @@ [app.main.style :as stl]) (:require [app.common.data :as d] + [app.main.constants :refer [max-input-length]] [app.main.ui.ds.controls.shared.options-dropdown :refer [options-dropdown*]] [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list] :as i] [app.util.array :as array] @@ -60,6 +61,7 @@ [:id {:optional true} :string] [:options [:vector schema:combobox-option]] [:class {:optional true} :string] + [:max-length {:optional true} :int] [:placeholder {:optional true} :string] [:disabled {:optional true} :boolean] [:default-selected {:optional true} :string] @@ -69,7 +71,7 @@ (mf/defc combobox* {::mf/props :obj ::mf/schema schema:combobox} - [{:keys [id options class placeholder disabled has-error default-selected on-change] :rest props}] + [{:keys [id options class placeholder disabled has-error default-selected on-change max-length] :rest props}] (let [open* (mf/use-state false) open (deref open*) @@ -240,6 +242,7 @@ :aria-activedescendant focused :class (stl/css :input) :data-testid "combobox-input" + :maxlength (d/nilv max-length max-input-length) :disabled disabled :value selected :on-change on-input-change diff --git a/frontend/src/app/main/ui/ds/controls/input.cljs b/frontend/src/app/main/ui/ds/controls/input.cljs index 266f15ef3..93674b4da 100644 --- a/frontend/src/app/main/ui/ds/controls/input.cljs +++ b/frontend/src/app/main/ui/ds/controls/input.cljs @@ -10,6 +10,7 @@ [app.main.style :as stl]) (:require [app.common.data :as d] + [app.main.constants :refer [max-input-length]] [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]] [app.util.dom :as dom] [rumext.v2 :as mf])) @@ -20,13 +21,14 @@ [:icon {:optional true} [:and :string [:fn #(contains? icon-list %)]]] [:type {:optional true} :string] + [:max-length {:optional true} :int] [:variant {:optional true} :string]]) (mf/defc input* {::mf/props :obj ::mf/forward-ref true ::mf/schema schema:input} - [{:keys [icon class type variant] :rest props} ref] + [{:keys [icon class type max-length variant] :rest props} ref] (let [ref (or ref (mf/use-ref)) type (d/nilv type "text") props (mf/spread-props props @@ -34,6 +36,7 @@ :input true :input-with-icon (some? icon)) :ref ref + :maxlength (d/nilv max-length (str max-input-length)) :type type}) on-icon-click diff --git a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens.cljs b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens.cljs index ad4e1ebce..3746e3217 100644 --- a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens.cljs @@ -7,7 +7,9 @@ (ns app.main.ui.workspace.tokens.components.controls.input-tokens (:require-macros [app.main.style :as stl]) (:require + [app.common.data :as d] [app.common.data.macros :as dm] + [app.main.constants :refer [max-input-length]] [app.main.ui.ds.controls.input :refer [input*]] [rumext.v2 :as mf])) @@ -18,6 +20,7 @@ [:placeholder {:optional true} :string] [:default-value {:optional true} [:maybe :string]] [:class {:optional true} :string] + [:max-length {:optional true} :int] [:error {:optional true} :boolean] [:value {:optional true} :string]]) @@ -25,12 +28,13 @@ {::mf/props :obj ::mf/forward-ref true ::mf/schema schema::input-tokens} - [{:keys [class label id error value children] :rest props} ref] + [{:keys [class label id max-length error value children] :rest props} ref] (let [ref (or ref (mf/use-ref)) props (mf/spread-props props {:id id :type "text" :class (stl/css :input) :aria-invalid error + :max-length (d/nilv max-length max-input-length) :value value :ref ref})] [:div {:class (dm/str class " " (stl/css-case :wrapper true diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index d07a99281..1f4c0799a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -205,6 +205,7 @@ [:> input-tokens* {:id "theme-input" :label (tr "workspace.token.label.theme") :type "text" + :max-length 256 :placeholder (tr "workspace.token.label.theme-placeholder") :on-change on-update-name :value (mf/ref-val theme-name-ref) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 7050e47a0..44785ed57 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -94,6 +94,7 @@ :type "text" :on-blur on-submit :on-key-down on-key-down + :maxlength "256" :auto-focus true :placeholder (tr "workspace.token.set-edit-placeholder") :default-value default-value}])) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss index 70d9584a6..8c287aee7 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss @@ -44,6 +44,11 @@ margin-bottom: $s-8; padding-left: $s-8; color: var(--title-foreground-color); + word-break: break-word; +} + +.sets-header { + margin-block-start: $s-8; } .themes-wrapper { From c259b8ed46b079e435ffbc011a33e06dbb0ff039 Mon Sep 17 00:00:00 2001 From: Xavier Julian Date: Wed, 26 Mar 2025 22:53:35 +0100 Subject: [PATCH 04/10] :bug: Fix overflow on tokens sidebar --- .../ui/workspace/tokens/modals/themes.cljs | 15 +++++----- .../ui/workspace/tokens/modals/themes.scss | 29 ++++++++++++------- .../app/main/ui/workspace/tokens/sets.cljs | 3 +- .../app/main/ui/workspace/tokens/sets.scss | 2 ++ .../app/main/ui/workspace/tokens/sidebar.cljs | 3 +- .../app/main/ui/workspace/tokens/sidebar.scss | 6 ++-- .../ui/workspace/tokens/theme_select.cljs | 4 +-- .../ui/workspace/tokens/theme_select.scss | 1 + 8 files changed, 38 insertions(+), 25 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 1f4c0799a..d6f98ff30 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -106,9 +106,9 @@ [:> heading* {:level 3 :class (stl/css :theme-group-label) :typography "body-large"} - [:span {:class (stl/css :group-title) :title (tr "workspace.token.group-name")} - [:> icon* {:icon-id "group"}] - group]]) + [:div {:class (stl/css :group-title) :title (str (tr "workspace.token.group-name") ": " group)} + [:> icon* {:icon-id "group" :class (stl/css :group-title-icon)}] + [:> text* {:as "span" :typography "body-medium" :class (stl/css :group-title-name)} group]]]) [:ul {:class (stl/css :theme-group-rows-wrapper)} (for [[_ {:keys [group name] :as theme}] themes :let [theme-id (ctob/theme-path theme) @@ -126,7 +126,7 @@ :theme-path [(:id theme) (:group theme) (:name theme)]})))]] [:li {:key theme-id :class (stl/css :theme-row)} - [:div {:class (stl/css :theme-row-left)} + [:div {:class (stl/css :theme-switch-row)} ;; FIXME: FIREEEEEEEEEE THIS [:div {:on-click (fn [e] @@ -135,11 +135,12 @@ (st/emit! (wdt/toggle-token-theme-active? group name)))} [:& switch {:name (tr "workspace.token.theme-name" name) :on-change (constantly nil) - :selected? selected?}]] - [:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name)} name]] + :selected? selected?}]]] + [:div {:class (stl/css :theme-name-row)} + [:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name) :title name} name]] - [:div {:class (stl/css :theme-row-right)} + [:div {:class (stl/css :theme-actions-row)} (let [sets-count (some-> theme :sets seq count)] [:> button* {:class (stl/css-case :sets-count-button sets-count :sets-count-empty-button (not sets-count)) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss index bb72ef542..9277b720b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.scss @@ -32,8 +32,8 @@ } .themes-modal-wrapper { - display: grid; - grid-template-rows: 0fr minmax(0, 1fr); + display: flex; + flex-direction: column; gap: $s-16; max-height: $s-688; } @@ -120,6 +120,15 @@ gap: $s-4; } +.group-title-icon { + flex-shrink: 0; +} + +.group-title-name { + flex-grow: 1; + @include textEllipsis; +} + .theme-group-rows-wrapper { display: flex; flex-direction: column; @@ -136,26 +145,26 @@ } .theme-row { - display: flex; align-items: center; - gap: $s-12; + display: flex; justify-content: space-between; + gap: $s-16; } -.theme-row-left { - display: flex; - align-items: center; - gap: $s-16; +.theme-name-row { + @include textEllipsis; + flex-grow: 1; } .theme-name { color: var(--color-foreground-primary); } -.theme-row-right { - display: flex; +.theme-actions-row { align-items: center; + display: flex; gap: $s-6; + flex-shrink: 0; } .sets-count-button { diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 44785ed57..dc8f5364d 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -227,6 +227,7 @@ :on-submit on-edit-submit'}] [:* [:div {:class (stl/css :set-name) + :title label :on-double-click on-double-click :id label-id} label] @@ -499,7 +500,7 @@ (when (fn? on-start-edition) (on-start-edition v))))] - [:fieldset {:class (stl/css :sets-list)} + [:div {:class (stl/css :sets-list)} (if ^boolean empty-state? [:> text* {:as "span" :typography "body-small" :class (stl/css :empty-state-message-sets)} (tr "workspace.token.no-sets-create")] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.scss b/frontend/src/app/main/ui/workspace/tokens/sets.scss index aa783329f..ca1e55d5b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sets.scss @@ -70,6 +70,7 @@ } .icon { + flex-shrink: 0; display: flex; align-items: center; width: $s-20; @@ -82,6 +83,7 @@ } .checkbox-style { + flex-shrink: 0; display: flex; justify-content: center; align-items: center; diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index e4b596a4e..8a3b3d150 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -319,8 +319,7 @@ [:* [:& token-context-menu] - [:& title-bar {:all-clickable true - :title (tr "workspace.token.tokens-section-title" selected-token-set-name)}] + [:span {:class (stl/css :sets-header)} (tr "workspace.token.tokens-section-title" selected-token-set-name)] (for [type filled-group] (let [tokens (get tokens-by-type type)] diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss index 8c287aee7..6828a4665 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.scss @@ -38,11 +38,11 @@ padding-block-end: $s-16; } -.themes-header { +.themes-header, +.sets-header { @include use-typography("headline-small"); display: block; - margin-bottom: $s-8; - padding-left: $s-8; + padding: $s-8; color: var(--title-foreground-color); word-break: break-word; } diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs index 5ef0fff00..9eaba56d9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.cljs @@ -41,7 +41,7 @@ :sub-item grouped? :is-selected selected?) :on-click select-theme} - [:> text* {:as "span" :typography "body-small" :class (stl/css :label)} name] + [:> text* {:as "span" :typography "body-small" :class (stl/css :label) :title name} name] [:> icon* {:icon-id i/tick :aria-hidden true :class (stl/css-case :check-icon true @@ -58,7 +58,7 @@ :aria-labelledby (dm/str group "-label") :role "group"} (when (seq group) - [:> text* {:as "span" :typography "headline-small" :class (stl/css :group) :id (dm/str group "-label")} group]) + [:> text* {:as "span" :typography "headline-small" :class (stl/css :group) :id (dm/str (str/kebab group) "-label") :title group} group]) [:& themes-list {:themes themes :active-theme-paths active-theme-paths :on-close on-close diff --git a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss index 170213a36..7819cfb62 100644 --- a/frontend/src/app/main/ui/workspace/tokens/theme_select.scss +++ b/frontend/src/app/main/ui/workspace/tokens/theme_select.scss @@ -41,6 +41,7 @@ } .group { + @include textEllipsis; display: block; padding: $s-8; color: var(--color-foreground-secondary); From 89876ef96f96ce6242cf1231c721c183c64bdc25 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Mon, 31 Mar 2025 15:33:30 +0200 Subject: [PATCH 05/10] :bug: Fix UI with long named colors (#6193) --- .../main/ui/inspect/attributes/common.scss | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/main/ui/inspect/attributes/common.scss b/frontend/src/app/main/ui/inspect/attributes/common.scss index 22be662af..5ea1fdf41 100644 --- a/frontend/src/app/main/ui/inspect/attributes/common.scss +++ b/frontend/src/app/main/ui/inspect/attributes/common.scss @@ -70,36 +70,23 @@ visibility: visible; } } + .one-line { max-height: $s-32; } + .two-line { display: grid; - grid-template-rows: 1fr 1fr; + grid-template-rows: auto 1fr; + gap: $s-4; } + .color-name-wrapper { @include bodySmallTypography; @include flexColumn; padding: $s-8 $s-4 $s-8 $s-8; height: $s-32; max-width: $s-80; - - &.gradient-color { - color: var(--menu-foreground-color); - max-width: $s-124; - } - .color-name-library { - @include bodySmallTypography; - @include textEllipsis; - text-align: left; - height: $s-16; - color: var(--menu-foreground-color-rest); - } - .color-value-wrapper { - @include bodySmallTypography; - height: $s-16; - color: var(--menu-foreground-color); - } } .opacity-info { @@ -152,6 +139,7 @@ .color-name-library { @include inspectValue; color: var(--menu-foreground-color-rest); + word-break: break-word; } .image-download { From 2c0e18ce1c5d32d8928cbcffc9c6edd260552117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Mon, 31 Mar 2025 14:22:33 +0200 Subject: [PATCH 06/10] :bug: Fix sync of margin and padding tokens in components --- common/src/app/common/logic/libraries.cljc | 16 +++++++++++++++- common/src/app/common/types/token.cljc | 21 +++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 95b71ccd6..ddce143e9 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -1639,7 +1639,21 @@ (if (and (empty? roperations) (empty? applied-tokens)) changes (let [all-parents (cfh/get-parent-ids (:objects container) - (:id dest-shape))] + (:id dest-shape)) + + ;; Sync tokens of attributes ignored above. + ;; FIXME: this probably may be merged with the other calculation + ;; of applied tokens, below, and to the calculation only once + ;; for all sync-attrs. + applied-tokens (reduce (fn [applied-tokens attr] + (let [attr-group (get ctk/sync-attrs attr) + token-attrs (cto/shape-attr->token-attrs attr)] + (if (not (and (touched attr-group) + omit-touched?)) + (into applied-tokens token-attrs) + applied-tokens))) + applied-tokens + ctk/swap-keep-attrs)] (cond-> changes (seq roperations) (-> (update :redo-changes conj (make-change diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index 12f5c5d3e..f269e2cca 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -182,14 +182,27 @@ ([shape-attr] (shape-attr->token-attrs shape-attr nil)) ([shape-attr changed-sub-attr] (cond - (= :fills shape-attr) #{:fill} - (and (= :strokes shape-attr) (nil? changed-sub-attr)) #{:stroke-width :stroke-color} + (= :fills shape-attr) + #{:fill} + + (and (= :strokes shape-attr) (nil? changed-sub-attr)) + #{:stroke-width :stroke-color} + (= :strokes shape-attr) (cond (some #{:stroke-color} changed-sub-attr) #{:stroke-color} (some #{:stroke-width} changed-sub-attr) #{:stroke-width}) - (and (= :layout-padding shape-attr) (seq changed-sub-attr)) changed-sub-attr - (and (= :layout-item-margin shape-attr) (seq changed-sub-attr)) changed-sub-attr + + (= :layout-padding shape-attr) + (if (seq changed-sub-attr) + changed-sub-attr + #{:p1 :p2 :p3 :p4}) + + (= :layout-item-margin shape-attr) + (if (seq changed-sub-attr) + changed-sub-attr + #{:m1 :m2 :m3 :m4}) + (border-radius-keys shape-attr) #{shape-attr} (sizing-keys shape-attr) #{shape-attr} (opacity-keys shape-attr) #{shape-attr} From 9663964790d598984b62c75c6e965911df6e66b1 Mon Sep 17 00:00:00 2001 From: Yamila Moreno Date: Tue, 1 Apr 2025 09:34:46 +0200 Subject: [PATCH 07/10] :whale: Make traefik example easier (#6198) --- docker/images/docker-compose.yaml | 28 +++++-------------- .../technical-guide/getting-started/docker.md | 13 +++++++++ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docker/images/docker-compose.yaml b/docker/images/docker-compose.yaml index aa215f36c..63caa5d00 100644 --- a/docker/images/docker-compose.yaml +++ b/docker/images/docker-compose.yaml @@ -52,7 +52,7 @@ services: ## penpot to the internet, or a different host than `localhost`. # traefik: - # image: traefik:v2.9 + # image: traefik:v3.3 # networks: # - penpot # command: @@ -88,28 +88,15 @@ services: - penpot labels: - - "traefik.enable=true" + # - "traefik.enable=true" - ## HTTP: example of labels for the case where penpot will be exposed to the - ## internet with only HTTP (without HTTPS) using traefik. + # ## HTTPS: example of labels for the case where penpot will be exposed to the + # ## internet with HTTPS using traefik. - # - "traefik.http.routers.penpot-http.entrypoints=web" - # - "traefik.http.routers.penpot-http.rule=Host(``)" - # - "traefik.http.services.penpot-http.loadbalancer.server.port=80" - - ## HTTPS: example of labels for the case where penpot will be exposed to the - ## internet with HTTPS using traefik. - - # - "traefik.http.middlewares.http-redirect.redirectscheme.scheme=https" - # - "traefik.http.middlewares.http-redirect.redirectscheme.permanent=true" - # - "traefik.http.routers.penpot-http.entrypoints=web" - # - "traefik.http.routers.penpot-http.rule=Host(``)" - # - "traefik.http.routers.penpot-http.middlewares=http-redirect" - # - "traefik.http.routers.penpot-https.entrypoints=websecure" # - "traefik.http.routers.penpot-https.rule=Host(``)" - # - "traefik.http.services.penpot-https.loadbalancer.server.port=80" - # - "traefik.http.routers.penpot-https.tls=true" + # - "traefik.http.routers.penpot-https.entrypoints=websecure" # - "traefik.http.routers.penpot-https.tls.certresolver=letsencrypt" + # - "traefik.http.routers.penpot-https.tls=true" environment: << : [*penpot-flags, *penpot-http-body-size] @@ -130,8 +117,7 @@ services: networks: - penpot - ## Configuration envronment variables for the backend - ## container. + ## Configuration envronment variables for the backend container. environment: << : [*penpot-flags, *penpot-public-uri, *penpot-http-body-size] diff --git a/docs/technical-guide/getting-started/docker.md b/docs/technical-guide/getting-started/docker.md index 118e85723..5b6e57993 100644 --- a/docs/technical-guide/getting-started/docker.md +++ b/docs/technical-guide/getting-started/docker.md @@ -200,6 +200,8 @@ server { } ``` +For full documentation, go to the [official website][2] + ### Example with CADDY SERVER ```bash @@ -212,4 +214,15 @@ penpot.mycompany.com { } ``` +For full documentation, go to the [official website][3] + +### Example with TRAEFIK + +In the [Penpot's docker-compose.yaml][4] file, there is a simple example with Traefik. +For full documentation, go to the [official website][5] + [1]: /technical-guide/configuration/ +[2]: https://nginx.org/en/docs/index.html +[3]: https://caddyserver.com/docs/ +[4]: https://github.com/penpot/penpot/blob/develop/docker/images/docker-compose.yaml +[5]: https://doc.traefik.io/traefik/ From a51feb86383d61888c2ee0c4208d413f521619d2 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 1 Apr 2025 10:47:13 +0200 Subject: [PATCH 08/10] :paperclip: Update changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index cd2b71aa5..8a96f1572 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ - Fix chat icon overlaps "Show" button in carrousel section [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) - Fix incorrect handling of background task result (now task rows are properly marked as completed) - Fix available size of resize handler [Taiga #10639](https://tree.taiga.io/project/penpot/issue/10639) +- Internal error when install a plugin by penpothub - Try plugin [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) ## 2.5.4 @@ -61,7 +62,6 @@ methods (add missing team-id prop) - Fix problem with viewer role and inspect mode [Taiga #9751](https://tree.taiga.io/project/penpot/issue/9751) - Fix error when clicking on a comment at the viewer's sidebar [Taiga #10465](https://tree.taiga.io/project/penpot/issue/10465) -- Internal error when install a plugin by penpothub - Try plugin [Taiga #10542](https://tree.taiga.io/project/penpot/issue/10542) ## 2.5.3 From 982118c9420e866bd884896c08894acfb517d61a Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 1 Apr 2025 10:47:49 +0200 Subject: [PATCH 09/10] :whale: Update devenv corepack setup --- docker/devenv/files/start-tmux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/devenv/files/start-tmux.sh b/docker/devenv/files/start-tmux.sh index b80e425cc..f3c7180ad 100755 --- a/docker/devenv/files/start-tmux.sh +++ b/docker/devenv/files/start-tmux.sh @@ -8,12 +8,12 @@ source ~/.bashrc echo "[start-tmux.sh] Installing node dependencies" pushd ~/penpot/frontend/ -corepack up; +corepack install; yarn install; yarn run playwright install --with-deps chromium popd pushd ~/penpot/exporter/ -corepack up; +corepack install; yarn install yarn run playwright install --with-deps chromium popd From a20dd3f95549467cbcb256e7cb306b21a6a06db7 Mon Sep 17 00:00:00 2001 From: Andrey Fedorov Date: Mon, 31 Mar 2025 18:38:17 +0200 Subject: [PATCH 10/10] :sparkles: Fix single set import --- common/src/app/common/types/tokens_lib.cljc | 66 +++++++++++------- .../types/data/legacy-single-set.json | 6 ++ .../common_tests/types/data/single-set.json | 6 ++ .../common_tests/types/tokens_lib_test.cljc | 24 +++++++ .../app/main/ui/workspace/tokens/sidebar.cljs | 6 +- .../ui/workspace/tokens/style_dictionary.cljs | 69 ++++++++++++------- 6 files changed, 127 insertions(+), 50 deletions(-) create mode 100644 common/test/common_tests/types/data/legacy-single-set.json create mode 100644 common/test/common_tests/types/data/single-set.json diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index f53c806d3..06b190340 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -665,20 +665,20 @@ ["$value" :map] ["$type" :string]]])) -(defn has-legacy-format? +(defn get-json-format "Searches through parsed token file and returns: - - true when first node satisfies `legacy-node?` predicate - - false when first node satisfies `dtcg-node?` predicate - - nil if neither combination is found" + - `:json-format/legacy` when first node satisfies `legacy-node?` predicate + - `:json-format/dtcg` when first node satisfies `dtcg-node?` predicate + - `nil` if neither combination is found" ([data] - (has-legacy-format? data legacy-node? dtcg-node?)) + (get-json-format data legacy-node? dtcg-node?)) ([data legacy-node? dtcg-node?] (let [branch? map? children (fn [node] (vals node)) check-node (fn [node] (cond - (legacy-node? node) true - (dtcg-node? node) false + (legacy-node? node) :json-format/legacy + (dtcg-node? node) :json-format/dtcg :else nil)) walk (fn walk [node] (lazy-seq @@ -690,6 +690,10 @@ (filter some?) first)))) +(defn single-set? [data] + (and (not (contains? data "$metadata")) + (not (contains? data "$themes")))) + ;; DEPRECATED (defn walk-sets-tree-seq "Walk sets tree as a flat list. @@ -826,6 +830,24 @@ (declare make-tokens-lib) +(defn- legacy-nodes->dtcg-nodes [sets-data] + (walk/postwalk + (fn [node] + (cond-> node + (and (map? node) + (contains? node "value") + (sequential? (get node "value"))) + (update "value" + (fn [seq-value] + (map #(set/rename-keys % {"type" "$type"}) seq-value))) + + (and (map? node) + (and (contains? node "type") + (contains? node "value"))) + (set/rename-keys {"value" "$value" + "type" "$type"}))) + sets-data)) + (defprotocol ITokensLib "A library of tokens, sets and themes." (set-path-exists? [_ path] "if a set at `path` exists") @@ -844,6 +866,8 @@ Will return a value that matches this schema: (get-active-themes-set-tokens [_] "set of set names that are active in the the active themes") (encode-dtcg [_] "Encodes library to a dtcg compatible json string") (decode-dtcg-json [_ parsed-json] "Decodes parsed json containing tokens and converts to library") + (decode-single-set-json [_ set-name tokens] "Decodes parsed json containing single token set and converts to library") + (decode-single-set-legacy-json [_ set-name tokens] "Decodes parsed legacy json containing single token set and converts to library") (decode-legacy-json [_ parsed-json] "Decodes parsed legacy json containing tokens and converts to library") (get-all-tokens [_] "all tokens in the lib") (validate [_])) @@ -1287,6 +1311,17 @@ Will return a value that matches this schema: (assoc-in ["$metadata" "activeThemes"] active-themes-clear) (assoc-in ["$metadata" "activeSets"] active-sets)))) + (decode-single-set-json [this set-name tokens] + (assert (map? tokens) "expected a map data structure for `data`") + + (add-set this (make-token-set :name (normalize-set-name set-name) + :tokens (flatten-nested-tokens-json tokens "")))) + + + (decode-single-set-legacy-json [this set-name tokens] + (assert (map? tokens) "expected a map data structure for `data`") + (decode-single-set-json this set-name (legacy-nodes->dtcg-nodes tokens))) + (decode-dtcg-json [_ data] (assert (map? data) "expected a map data structure for `data`") @@ -1370,22 +1405,7 @@ Will return a value that matches this schema: (decode-legacy-json [this parsed-legacy-json] (let [other-data (select-keys parsed-legacy-json ["$themes" "$metadata"]) sets-data (dissoc parsed-legacy-json "$themes" "$metadata") - dtcg-sets-data (walk/postwalk - (fn [node] - (cond-> node - (and (map? node) - (contains? node "value") - (sequential? (get node "value"))) - (update "value" - (fn [seq-value] - (map #(set/rename-keys % {"type" "$type"}) seq-value))) - - (and (map? node) - (and (contains? node "type") - (contains? node "value"))) - (set/rename-keys {"value" "$value" - "type" "$type"}))) - sets-data)] + dtcg-sets-data (legacy-nodes->dtcg-nodes sets-data)] (decode-dtcg-json this (merge other-data dtcg-sets-data)))) (get-all-tokens [this] diff --git a/common/test/common_tests/types/data/legacy-single-set.json b/common/test/common_tests/types/data/legacy-single-set.json new file mode 100644 index 000000000..e69153a76 --- /dev/null +++ b/common/test/common_tests/types/data/legacy-single-set.json @@ -0,0 +1,6 @@ +{"color": + {"red": + {"100": + {"value":"red", + "type":"color", + "description":""}}}} diff --git a/common/test/common_tests/types/data/single-set.json b/common/test/common_tests/types/data/single-set.json new file mode 100644 index 000000000..d558781ae --- /dev/null +++ b/common/test/common_tests/types/data/single-set.json @@ -0,0 +1,6 @@ +{"color": + {"red": + {"100": + {"$value":"red", + "$type":"color", + "$description":""}}}} diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index 0b80eed16..0a41f37e5 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -1371,6 +1371,30 @@ (t/testing "invalid tokens got discarded" (t/is (nil? (get-set-token "typography" "H1.Bold"))))))) +#?(:clj + (t/deftest single-set-legacy-json-decoding + (let [json (-> (slurp "test/common_tests/types/data/legacy-single-set.json") + (tr/decode-str)) + lib (ctob/decode-single-set-legacy-json (ctob/ensure-tokens-lib nil) "single_set" json) + get-set-token (fn [set-name token-name] + (some-> (ctob/get-set lib set-name) + (ctob/get-token token-name)))] + (t/is (= '("single_set") (ctob/get-ordered-set-names lib))) + (t/testing "token added" + (t/is (some? (get-set-token "single_set" "color.red.100"))))))) + +#?(:clj + (t/deftest single-set-dtcg-json-decoding + (let [json (-> (slurp "test/common_tests/types/data/single-set.json") + (tr/decode-str)) + lib (ctob/decode-single-set-json (ctob/ensure-tokens-lib nil) "single_set" json) + get-set-token (fn [set-name token-name] + (some-> (ctob/get-set lib set-name) + (ctob/get-token token-name)))] + (t/is (= '("single_set") (ctob/get-ordered-set-names lib))) + (t/testing "token added" + (t/is (some? (get-set-token "single_set" "color.red.100"))))))) + #?(:clj (t/deftest dtcg-encoding-decoding-json (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 8a3b3d150..5cb6da341 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -40,6 +40,7 @@ [app.util.i18n :refer [tr]] [app.util.webapi :as wapi] [beicon.v2.core :as rx] + [cuerdas.core :as str] [okulary.core :as l] [potok.v2.core :as ptk] [rumext.v2 :as mf] @@ -367,9 +368,10 @@ (fn [event] (let [file (-> (dom/get-target event) (dom/get-files) - (first))] + (first)) + file-name (str/replace (.-name file) ".json" "")] (->> (wapi/read-file-as-text file) - (sd/process-json-stream) + (sd/process-json-stream {:file-name file-name}) (rx/subs! (fn [lib] (st/emit! (ptk/data-event ::ev/event {::ev/name "import-tokens"}) (dt/import-tokens-lib lib))) diff --git a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs index d6fc48b7c..a31f0635a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs @@ -6,6 +6,7 @@ [app.common.schema :as sm] [app.common.transit :as t] [app.common.types.tokens-lib :as ctob] + [app.main.refs :as refs] [app.main.ui.workspace.tokens.errors :as wte] [app.main.ui.workspace.tokens.tinycolor :as tinycolor] [app.main.ui.workspace.tokens.token :as wtt] @@ -249,33 +250,51 @@ (= header-2 "Reference Errors:")) errors))) -(defn process-json-stream [data-stream] - (->> data-stream - (rx/map (fn [data] - (try - (t/decode-str data) - (catch js/Error e - (throw (wte/error-ex-info :error.import/json-parse-error data e)))))) - (rx/map (fn [json-data] - (try - (if-not (ctob/has-legacy-format? json-data) - (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json-data) - (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json-data)) - (catch js/Error e - (throw (wte/error-ex-info :error.import/invalid-json-data json-data e)))))) - (rx/mapcat (fn [tokens-lib] +(defn process-json-stream + ([data-stream] + (process-json-stream nil data-stream)) + ([params data-stream] + (let [{:keys [file-name]} params] + (->> data-stream + (rx/map (fn [data] (try - (-> (ctob/get-all-tokens tokens-lib) - (resolve-tokens-with-errors+) - (p/then (fn [_] tokens-lib)) - (p/catch (fn [sd-error] - (let [reference-errors (reference-errors sd-error) - err (if reference-errors - (wte/error-ex-info :error.import/style-dictionary-reference-errors reference-errors sd-error) - (wte/error-ex-info :error.import/style-dictionary-unknown-error sd-error sd-error))] - (throw err))))) + (t/decode-str data) (catch js/Error e - (p/rejected (wte/error-ex-info :error.import/style-dictionary-unknown-error "" e)))))))) + (throw (wte/error-ex-info :error.import/json-parse-error data e)))))) + (rx/map (fn [json-data] + (let [single-set? (ctob/single-set? json-data) + json-format (ctob/get-json-format json-data)] + (try + (cond + (and single-set? + (= :json-format/legacy json-format)) + (ctob/decode-single-set-legacy-json (ctob/ensure-tokens-lib (deref refs/tokens-lib)) file-name json-data) + + (and single-set? + (= :json-format/dtcg json-format)) + (ctob/decode-single-set-json (ctob/ensure-tokens-lib (deref refs/tokens-lib)) file-name json-data) + + (= :json-format/legacy json-format) + (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json-data) + + :else + (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json-data)) + + (catch js/Error e + (throw (wte/error-ex-info :error.import/invalid-json-data json-data e))))))) + (rx/mapcat (fn [tokens-lib] + (try + (-> (ctob/get-all-tokens tokens-lib) + (resolve-tokens-with-errors+) + (p/then (fn [_] tokens-lib)) + (p/catch (fn [sd-error] + (let [reference-errors (reference-errors sd-error) + err (if reference-errors + (wte/error-ex-info :error.import/style-dictionary-reference-errors reference-errors sd-error) + (wte/error-ex-info :error.import/style-dictionary-unknown-error sd-error sd-error))] + (throw err))))) + (catch js/Error e + (p/rejected (wte/error-ex-info :error.import/style-dictionary-unknown-error "" e)))))))))) ;; === Errors