0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-03 21:09:00 -05:00

Merge pull request #179 from uxbox/fixes-2020-04-15

Bugfixes
This commit is contained in:
Hirunatan 2020-04-16 11:25:41 +02:00 committed by GitHub
commit f5e16eb469
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 681 additions and 699 deletions

View file

@ -54,14 +54,25 @@
(t/is (= [id-b id-c id-a] (get-in res [:objects uuid/zero :shapes])))))))
(t/deftest process-change-mod-obj
(let [data cp/default-page-data
chg {:type :mod-obj
:id uuid/zero
:operations [{:type :set
:attr :name
:val "foobar"}]}
res (cp/process-changes data [chg])]
(t/is (= "foobar" (get-in res [:objects uuid/zero :name])))))
(t/testing "simple mod-obj"
(let [data cp/default-page-data
chg {:type :mod-obj
:id uuid/zero
:operations [{:type :set
:attr :name
:val "foobar"}]}
res (cp/process-changes data [chg])]
(t/is (= "foobar" (get-in res [:objects uuid/zero :name])))))
(t/testing "mod-obj for not existing shape"
(let [data cp/default-page-data
chg {:type :mod-obj
:id (uuid/next)
:operations [{:type :set
:attr :name
:val "foobar"}]}
res (cp/process-changes data [chg])]
(t/is (= res cp/default-page-data)))))
(t/deftest process-change-del-obj-1
@ -202,15 +213,15 @@
))
(t/deftest process-changes-move-objects
(let [frame-a-id (uuid/next)
frame-b-id (uuid/next)
group-a-id (uuid/next)
group-b-id (uuid/next)
rect-a-id (uuid/next)
rect-b-id (uuid/next)
rect-c-id (uuid/next)
rect-d-id (uuid/next)
rect-e-id (uuid/next)
(let [frame-a-id (uuid/custom 1)
frame-b-id (uuid/custom 2)
group-a-id (uuid/custom 3)
group-b-id (uuid/custom 4)
rect-a-id (uuid/custom 5)
rect-b-id (uuid/custom 6)
rect-c-id (uuid/custom 7)
rect-d-id (uuid/custom 8)
rect-e-id (uuid/custom 9)
data (-> cp/default-page-data
(assoc-in [cp/root :shapes] [frame-a-id])
(assoc-in [:objects frame-a-id]
@ -345,12 +356,47 @@
(t/is (= data res))))))
(t/deftest process-changes-move-objects-3
(let [shape-2-id (uuid/custom 1 2)
shape-3-id (uuid/custom 1 3)
frame-id (uuid/custom 1 1)
changes [{:type :add-obj
:id frame-id
:frame-id uuid/zero
:obj {:type :frame
:name "Frame"}}
{:type :add-obj
:frame-id frame-id
:id shape-2-id
:obj {:type :shape
:name "Shape"}}
{:type :add-obj
:id shape-3-id
:frame-id uuid/zero
:obj {:type :rect
:name "Shape"}}]
data (cp/process-changes cp/default-page-data changes)]
(t/testing "move inside->outside-inside"
(let [changes [{:type :mov-objects
:shapes [shape-3-id]
:parent-id frame-id}
{:type :mov-objects
:shapes [shape-3-id]
:parent-id uuid/zero}]
res (cp/process-changes data changes)]
(t/is (= (get-in res [:objects shape-2-id :frame-id])
(get-in data [:objects shape-2-id :frame-id])))
(t/is (= (get-in res [:objects shape-3-id :frame-id])
(get-in data [:objects shape-3-id :frame-id])))))))
(t/deftest process-changes-move-objects-2
(let [shape-1-id (uuid/custom 1 1)
shape-2-id (uuid/custom 1 2)
shape-3-id (uuid/custom 1 3)
shape-4-id (uuid/custom 1 4)
group-1-id (uuid/custom 2 1)
group-1-id (uuid/custom 1 5)
changes [{:type :add-obj
:id shape-1-id
:frame-id cp/root

View file

@ -139,7 +139,7 @@
(defmethod change-spec-impl :add-obj [_]
(s/keys :req-un [::id ::frame-id ::obj]
:opt-un [::session-id]))
:opt-un [::session-id ::parent-id]))
(defmethod change-spec-impl :mod-obj [_]
(s/keys :req-un [::id ::operations]
@ -149,10 +149,6 @@
(s/keys :req-un [::id]
:opt-un [::session-id]))
(defmethod change-spec-impl :mov-obj [_]
(s/keys :req-un [::id ::frame-id]
:opt-un [::session-id]))
(defmethod change-spec-impl :mov-objects [_]
(s/keys :req-un [::parent-id ::shapes]
:opt-un [::index]))
@ -194,40 +190,39 @@
(defn process-changes
[data items]
(->> (us/verify ::changes items)
(reduce #(or (process-change %1 %2) %1) data)))
(reduce #(do
;; (prn "process-change" (:type %2) (:id %2))
(or (process-change %1 %2) %1))
data)))
(declare insert-at-index)
(defmethod process-change :add-obj
[data {:keys [id obj frame-id index] :as change}]
(assert (contains? (:objects data) frame-id) "process-change/add-obj")
(let [obj (assoc obj
[data {:keys [id obj frame-id parent-id index] :as change}]
(let [parent-id (or parent-id frame-id)
objects (:objects data)]
(when (and (contains? objects parent-id)
(contains? objects frame-id))
(let [obj (assoc obj
:frame-id frame-id
:id id)]
(-> data
(update :objects assoc id obj)
(update-in [:objects frame-id :shapes]
(fn [shapes]
(cond
(some #{id} shapes) shapes
(nil? index) (conj shapes id)
:else (insert-at-index shapes index [id])))))))
(-> data
(update :objects assoc id obj)
(update-in [:objects parent-id :shapes]
(fn [shapes]
(let [shapes (or shapes [])]
(cond
(some #{id} shapes) shapes
(nil? index) (conj shapes id)
:else (insert-at-index shapes index [id]))))))))))
(defmethod process-change :mod-obj
[data {:keys [id operations] :as change}]
(assert (contains? (:objects data) id) "process-change/mod-obj")
(update-in data [:objects id]
#(reduce process-operation % operations)))
(defmethod process-change :mov-obj
[data {:keys [id frame-id] :as change}]
(assert (contains? (:objects data) frame-id))
(let [frame-id' (get-in data [:objects id :frame-id])]
(when (not= frame-id frame-id')
(-> data
(update-in [:objects frame-id' :shapes] (fn [s] (filterv #(not= % id) s)))
(update-in [:objects id] assoc :frame-id frame-id)
(update-in [:objects frame-id :shapes] conj id)))))
(update data :objects
(fn [objects]
(if-let [obj (get objects id)]
(assoc objects id (reduce process-operation obj operations))
objects))))
(defmethod process-change :del-obj
[data {:keys [id] :as change}]
@ -237,7 +232,7 @@
(contains? (:objects data) frame-id)
(update-in [:objects frame-id :shapes] (fn [s] (filterv #(not= % id) s)))
(seq shapes) ; Recursive delete all dependend objects
(seq shapes) ; Recursive delete all dependend objects
(as-> $ (reduce #(or (process-change %1 {:type :del-obj :id %2}) %1) $ shapes))))))
(defn- calculate-child-parent-map
@ -275,7 +270,7 @@
(let [invalid (calculate-invalid-targets shape-id (:objects data))]
(not (invalid parent-id))))
valid? (every? is-valid-move shapes)
valid? (every? is-valid-move shapes)
;; Add items into the :shapes property of the target parent-id
insert-items
@ -283,7 +278,12 @@
(let [prev-shapes (or prev-shapes [])]
(if index
(insert-at-index prev-shapes index shapes)
(into prev-shapes shapes))))
(reduce (fn [acc id]
(if (some #{id} acc)
acc
(conj acc id)))
prev-shapes
shapes))))
strip-id
(fn [id]
@ -316,17 +316,18 @@
;; Updates the frame-id references that might be outdated
update-frame-ids
(fn update-frame-ids [data shape-id]
(as-> data $
(assoc-in $ [:objects shape-id :frame-id] frame-id)
(reduce update-frame-ids $ (get-in $ [:objects shape-id :shapes]))))]
(fn update-frame-ids [data id]
(let [data (assoc-in data [:objects id :frame-id] frame-id)
obj (get-in data [:objects id])]
(cond-> data
(not= :frame (:type obj))
(as-> $$ (reduce update-frame-ids $$ (:shapes obj))))))]
(if valid?
(when valid?
(as-> data $
(update-in $ [:objects parent-id :shapes] insert-items)
(reduce remove-in-parent $ shapes)
(reduce update-frame-ids $ (get-in $ [:objects parent-id :shapes])))
data)))
(reduce update-frame-ids $ (get-in $ [:objects parent-id :shapes]))))))
(defmethod process-operation :set
[shape op]

View file

@ -54,9 +54,9 @@
"dev": true
},
"@types/react": {
"version": "16.9.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.27.tgz",
"integrity": "sha512-j+RvQb9w7a2kZFBOgTh+s/elCwtqWUMN6RJNdmz0ntmwpeoMHKnyhUcmYBu7Yw94Rtj9938D+TJSn6WGcq2+OA==",
"version": "16.9.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.34.tgz",
"integrity": "sha512-8AJlYMOfPe1KGLKyHpflCg5z46n0b5DbRfqDksxBLBTUpB75ypDBAO9eCUcjNwE6LCUslwTz00yyG/X9gaVtow==",
"requires": {
"@types/prop-types": "*",
"csstype": "^2.2.0"
@ -375,13 +375,13 @@
"dev": true
},
"autoprefixer": {
"version": "9.7.5",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.5.tgz",
"integrity": "sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==",
"version": "9.7.6",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.6.tgz",
"integrity": "sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ==",
"dev": true,
"requires": {
"browserslist": "^4.11.0",
"caniuse-lite": "^1.0.30001036",
"browserslist": "^4.11.1",
"caniuse-lite": "^1.0.30001039",
"chalk": "^2.4.2",
"normalize-range": "^0.1.2",
"num2fraction": "^1.2.2",
@ -650,15 +650,15 @@
}
},
"browserslist": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.0.tgz",
"integrity": "sha512-WqEC7Yr5wUH5sg6ruR++v2SGOQYpyUdYYd4tZoAq1F7y+QXoLoYGXVbxhtaIqWmAJjtNTRjVD3HuJc1OXTel2A==",
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz",
"integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001035",
"electron-to-chromium": "^1.3.380",
"node-releases": "^1.1.52",
"pkg-up": "^3.1.0"
"caniuse-lite": "^1.0.30001038",
"electron-to-chromium": "^1.3.390",
"node-releases": "^1.1.53",
"pkg-up": "^2.0.0"
}
},
"buffer": {
@ -731,9 +731,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001038",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz",
"integrity": "sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ==",
"version": "1.0.30001042",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001042.tgz",
"integrity": "sha512-igMQ4dlqnf4tWv0xjaaE02op9AJ2oQzXKjWf4EuAHFN694Uo9/EfPVIPJcmn2WkU9RqozCxx5e2KPcVClHDbDw==",
"dev": true
},
"caseless": {
@ -1041,9 +1041,9 @@
}
},
"core-js-pure": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz",
"integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw=="
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
"integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA=="
},
"core-util-is": {
"version": "1.0.2",
@ -1139,9 +1139,9 @@
"dev": true
},
"css-selector-parser": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.3.0.tgz",
"integrity": "sha1-XxrUPi2O77/cME/NOaUhZklD4+s=",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
"integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==",
"dev": true
},
"css-tree": {
@ -1200,9 +1200,9 @@
"dev": true
},
"csstype": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz",
"integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q=="
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
"integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
},
"d": {
"version": "1.0.1",
@ -1224,9 +1224,9 @@
}
},
"date-fns": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.11.1.tgz",
"integrity": "sha512-3RdUoinZ43URd2MJcquzBbDQo+J87cSzB8NkXdZiN5ia1UNyep0oCyitfiL88+R7clGTeq/RniXAc16gWyAu1w=="
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.12.0.tgz",
"integrity": "sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw=="
},
"dateformat": {
"version": "3.0.3",
@ -1461,9 +1461,9 @@
}
},
"electron-to-chromium": {
"version": "1.3.390",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.390.tgz",
"integrity": "sha512-4RvbM5x+002gKI8sltkqWEk5pptn0UnzekUx8RTThAMPDSb8jjpm6SwGiSnEve7f85biyZl8DMXaipaCxDjXag==",
"version": "1.3.409",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.409.tgz",
"integrity": "sha512-CB2HUXiMsaVYY5VvcpELhDShiTRhI2FfN7CuacEZ5mDmMFuSG/ZVm8HoSya0+S61RvUd3TjIjFSKywqHZpRPzQ==",
"dev": true
},
"elliptic": {
@ -1809,9 +1809,9 @@
},
"dependencies": {
"mkdirp": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
@ -1901,12 +1901,12 @@
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
"locate-path": "^2.0.0"
}
},
"findup-sync": {
@ -2821,13 +2821,13 @@
}
},
"gulp-mustache": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/gulp-mustache/-/gulp-mustache-4.1.2.tgz",
"integrity": "sha512-4nJKL6akiP77Znbog2my7XbJ94VnS8HmMBwLYvUNoSYmD99I9vCopIok6XXT1nOu0zXztc5HxQ2PndYt06PWAQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/gulp-mustache/-/gulp-mustache-5.0.0.tgz",
"integrity": "sha512-8tk0R1Fd+l6+e/t954e3UheFo25dKkTapPLD1sWoSroPXfIPxyHVgbhfH5VJGqeXl3te5GOwPtfcxxZJ+PYoFg==",
"dev": true,
"requires": {
"escape-string-regexp": "^2.0.0",
"mustache": "^3.0.1",
"mustache": "^4.0.1",
"plugin-error": "^1.0.0",
"replace-ext": "^1.0.0",
"through2": "^3.0.1"
@ -3498,12 +3498,12 @@
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"p-locate": "^2.0.0",
"path-exists": "^3.0.0"
}
},
@ -3877,9 +3877,9 @@
}
},
"mkdirp": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz",
"integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
},
"mocha": {
@ -3962,9 +3962,9 @@
"dev": true
},
"mustache": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz",
"integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.1.tgz",
"integrity": "sha512-yL5VE97+OXn4+Er3THSmTdCFCtx5hHWzrolvH+JObZnUYwuaG7XV+Ch4fR2cIrcYI0tFHxS7iyFYl14bW8y2sA==",
"dev": true
},
"mute-stdout": {
@ -4318,27 +4318,27 @@
"dev": true
},
"p-limit": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
"integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
"p-try": "^1.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
"p-limit": "^1.1.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
"dev": true
},
"pako": {
@ -4525,12 +4525,12 @@
}
},
"pkg-up": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
"integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
"integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
"dev": true,
"requires": {
"find-up": "^3.0.0"
"find-up": "^2.1.0"
}
},
"plugin-error": {
@ -4993,9 +4993,9 @@
"dev": true
},
"resolve": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz",
"integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
@ -5052,9 +5052,9 @@
}
},
"rxjs": {
"version": "7.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.0.0-alpha.1.tgz",
"integrity": "sha512-wQB1ZRQysSXSXzPHhhsw+OaVmNnVSylgR3UkUvVEfexkDmfHEs9bpDz1oiMfIG9JL1hPXL1ABtrL0H6XhstbWg==",
"version": "7.0.0-beta.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.0.0-beta.0.tgz",
"integrity": "sha512-MMsqDczs2RzsTvBiH6SKjJkdAh7WaI6Q0axP/DX+1ljwFm6+18AhQ3kVT8gD7G0dHIVfh5hDFoqLaW79pkiGag==",
"requires": {
"tslib": "^1.9.0"
}
@ -5165,9 +5165,9 @@
}
},
"shadow-cljs": {
"version": "2.8.94",
"resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.8.94.tgz",
"integrity": "sha512-o3ykB9TpCnMGem4cjmbAkVeYe/saGMVl6RhC/BdO1UNlhPZUp3hwdVp9mBDN079O5jJEtC8RmjHY6xe9utYokw==",
"version": "2.8.95",
"resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.8.95.tgz",
"integrity": "sha512-2y5wgD3Bjbtu9hX6kRf7fzWHDga5BzW9CWU+eTrwddX0B2XbcoIKOiHYQTj6QrFFqYc1vkWGZLyYE9kEYN8N0A==",
"dev": true,
"requires": {
"node-libs-browser": "^2.0.0",
@ -5597,24 +5597,46 @@
"strip-ansi": "^3.0.0"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"string.prototype.trimend": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"es-abstract": "^1.17.5"
}
},
"string.prototype.trimleft": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
"integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5",
"string.prototype.trimstart": "^1.0.0"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
"integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"es-abstract": "^1.17.5",
"string.prototype.trimend": "^1.0.0"
}
},
"string.prototype.trimstart": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
"integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"string_decoder": {
@ -5721,6 +5743,15 @@
"wrap-ansi": "^2.0.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
@ -5742,15 +5773,31 @@
"invert-kv": "^2.0.0"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"mkdirp": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"mustache": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz",
"integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==",
"dev": true
},
"os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
@ -5762,6 +5809,30 @@
"mem": "^4.0.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@ -5841,9 +5912,9 @@
},
"dependencies": {
"mkdirp": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"

View file

@ -13,22 +13,22 @@
],
"scripts": {},
"devDependencies": {
"autoprefixer": "^9.7.4",
"autoprefixer": "^9.7.6",
"clean-css": "^4.2.3",
"gulp": "4.0.2",
"gulp-gzip": "^1.4.2",
"gulp-if": "^3.0.0",
"gulp-mustache": "^4.1.2",
"gulp-mustache": "^5.0.0",
"gulp-rename": "^2.0.0",
"gulp-svg-sprite": "^1.5.0",
"mkdirp": "^1.0.3",
"mkdirp": "^1.0.4",
"postcss": "^7.0.27",
"rimraf": "^3.0.0",
"sass": "^1.26.0",
"shadow-cljs": "^2.8.94"
"shadow-cljs": "^2.8.95"
},
"dependencies": {
"date-fns": "^2.11.1",
"date-fns": "^2.12.0",
"mousetrap": "^1.6.5",
"randomcolor": "^0.5.4",
"react": "^16.13.1",
@ -36,7 +36,7 @@
"react-dnd": "^10.0.2",
"react-dnd-html5-backend": "^10.0.2",
"react-dom": "^16.13.1",
"rxjs": "^7.0.0-alpha.1",
"rxjs": "^7.0.0-beta.0",
"source-map-support": "^0.5.16",
"tdigest": "^0.1.1",
"xregexp": "^4.3.0"

View file

@ -7,16 +7,15 @@
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.data.helpers)
(ns uxbox.main.data.helpers
(:require [uxbox.common.data :as d]))
(defn get-children
"Retrieve all children ids recursively for a given shape"
[shape-id objects]
(let [shapes (get-in objects [shape-id :shapes])]
(if shapes
(concat
shapes
(mapcat #(get-children % objects) shapes))
(d/concat shapes (mapcat #(get-children % objects) shapes))
[])))
(defn is-shape-grouped
@ -25,11 +24,11 @@
(let [contains-shape-fn
(fn [{:keys [shapes]}] ((set shapes) shape-id))
shapes (remove #(= (:type %) :frame) (vals objects))]
shapes (remove #(= (:type %) :frame) (vals objects))]
(some contains-shape-fn shapes)))
(defn get-parent
"Retrieve the id of the parent for the shape-id (if exists"
"Retrieve the id of the parent for the shape-id (if exists)"
[shape-id objects]
(let [check-parenthood
(fn [shape] (when (and (:shapes shape)
@ -55,9 +54,10 @@
(rec-fn shape-id [])))
(defn replace-shapes
"Replace inside shapes the value `to-replace-id` for the value in items keeping the same order.
`to-replace-id` can be a set, a sequable or a single value. Any of these will be changed into a
set to make the replacement"
"Replace inside shapes the value `to-replace-id` for the value in
items keeping the same order. `to-replace-id` can be a set, a
sequable or a single value. Any of these will be changed into a set
to make the replacement"
[shape to-replace-id items]
(let [should-replace
(cond

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@
[uxbox.main.store :as st]
[uxbox.main.ui.dashboard :refer [dashboard]]
[uxbox.main.ui.login :refer [login-page]]
[uxbox.main.ui.not-found :refer [not-found-page]]
[uxbox.main.ui.static :refer [not-found-page not-authorized-page]]
[uxbox.main.ui.profile.recovery :refer [profile-recovery-page]]
[uxbox.main.ui.profile.recovery-request :refer [profile-recovery-request-page]]
[uxbox.main.ui.profile.register :refer [profile-register-page]]
@ -47,6 +47,7 @@
["/view/:page-id" :viewer]
["/not-found" :not-found]
["/not-authorized" :not-authorized]
(when *assert*
["/debug/icons-preview" :debug-icons-preview])
@ -132,8 +133,11 @@
:page-id page-id
:key file-id}])
:not-authorized
[:& not-authorized-page]
:not-found
[:& not-found-page {}]))
[:& not-found-page]))
(mf/defc app
[]

View file

@ -7,7 +7,7 @@
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.ui.not-found
(ns uxbox.main.ui.static
(:require
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]
@ -15,7 +15,6 @@
(mf/defc not-found-page
[{:keys [error] :as props}]
(js/console.log "not-found" error)
[:section.not-found-layout
[:div.not-found-header i/logo]
[:div.not-found-content
@ -25,3 +24,14 @@
[:div.desc-message "Oops! Page not found"]
[:a.btn-primary.btn-small "Go back"]]]])
(mf/defc not-authorized-page
[{:keys [error] :as props}]
[:section.not-found-layout
[:div.not-found-header i/logo]
[:div.not-found-content
[:div.message-container
[:div.error-img i/icon-lock]
[:div.main-message "403"]
[:div.desc-message "Sorry, you are not authorized to access this page."]
#_[:a.btn-primary.btn-small "Go back"]]]])

View file

@ -32,30 +32,14 @@
[uxbox.main.ui.workspace.left-toolbar :refer [left-toolbar]]
[uxbox.util.data :refer [classnames]]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]
[uxbox.util.rdnd :as rdnd]))
[uxbox.util.geom.point :as gpt]))
;; --- Workspace
;; (defn- on-scroll
;; [event]
;; (let [target (.-target event)
;; top (.-scrollTop target)
;; left (.-scrollLeft target)]
;; (st/emit! (ms/->ScrollEvent (gpt/point left top)))))
;; (defn- on-wheel
;; [event frame]
;; (when (kbd/ctrl? event)
;; (let [dom (mf/ref-val frame)
;; scroll-position (scroll/get-current-position-absolute dom)
;; mouse-point @ms/mouse-position]
;; (scroll/scroll-to-point dom mouse-point scroll-position))))
(mf/defc workspace-content
[{:keys [page file layout] :as params}]
(let [frame (mf/use-ref nil)
left-sidebar? (not (empty? (keep layout [:layers :sitemap :document-history :libraries])))
(let [left-sidebar? (not (empty? (keep layout [:layers :sitemap
:document-history :libraries])))
right-sidebar? (not (empty? (keep layout [:icons :drawtools :element-options])))
classes (classnames
:no-tool-bar-right (not right-sidebar?)
@ -67,12 +51,7 @@
[:& messages]
[:& context-menu]
[:section.workspace-content
{:class classes
;; :on-scroll on-scroll
;; :on-wheel #(on-wheel % frame)
}
[:section.workspace-content {:class classes}
[:& history-dialog]
;; Rules
@ -81,12 +60,10 @@
[:& horizontal-rule]
[:& vertical-rule]])
[:section.workspace-viewport {:id "workspace-viewport"
:ref frame}
[:section.workspace-viewport {:id "workspace-viewport"}
[:& viewport {:page page :file file}]]]
[:& left-toolbar {:page page
:layout layout}]
[:& left-toolbar {:page page :layout layout}]
;; Aside
(when left-sidebar?
@ -94,21 +71,20 @@
(when right-sidebar?
[:& right-sidebar {:page page :layout layout}])]))
(mf/defc workspace
[{:keys [project-id file-id page-id] :as props}]
(-> (mf/deps file-id page-id)
(mf/use-effect
(fn []
(st/emit! (dw/initialize project-id file-id page-id))
#(st/emit! (dw/finalize project-id file-id page-id)))))
(mf/use-effect
(mf/deps file-id page-id)
(fn []
(st/emit! (dw/initialize project-id file-id page-id))
#(st/emit! (dw/finalize project-id file-id page-id))))
(-> (mf/deps file-id)
(mf/use-effect
(fn []
(st/emit! (dw/initialize-ws file-id))
#(st/emit! (dw/finalize-ws file-id)))))
(mf/use-effect
(mf/deps file-id)
(fn []
(st/emit! (dw/initialize-ws file-id))
#(st/emit! (dw/finalize-ws file-id))))
(hooks/use-shortcuts dw/shortcuts)

View file

@ -58,8 +58,8 @@
do-hide-shape #(st/emit! (dw/hide-shape (:id shape)))
do-lock-shape #(st/emit! (dw/block-shape (:id shape)))
do-unlock-shape #(st/emit! (dw/unblock-shape (:id shape)))
do-create-group #(st/emit! (dw/create-group))
do-remove-group #(st/emit! (dw/remove-group))]
do-create-group #(st/emit! dw/create-group)
do-remove-group #(st/emit! dw/remove-group)]
[:*
[:& menu-entry {:title "Copy"
:shortcut "Ctrl + c"

View file

@ -275,10 +275,7 @@
shape)
shape (dissoc shape ::initialized? :resize-modifier)]
;; Add & select the created shape to the workspace
(rx/of dw/deselect-all
(if (= :frame (:type shape))
(dw/add-frame shape)
(dw/add-shape shape))))))))))
(rx/of dw/deselect-all (dw/add-shape shape)))))))))
(def close-drawing-path
(ptk/reify ::close-drawing-path