mirror of
https://github.com/penpot/penpot.git
synced 2025-04-15 16:31:25 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
c0919aff51
110 changed files with 1849 additions and 1757 deletions
CHANGES.md
common
src/app/common
test/common_tests/logic
frontend
playwright
data/workspace
get-comment-threads-not-empty.jsonget-file-not-empty.jsonget-thread-comments.jsonupdate-comment-thread-status.json
ui
resources
images/form
styles/common/refactor
src/app
main
data/workspace
style.cljui.cljsui
auth.cljsauth.scss
auth
comments.cljscomments.scsscomponents
dashboard
debug
onboarding.cljsonboarding.scssonboarding
settings
viewer
workspace
util
worker
translations
|
@ -20,15 +20,17 @@
|
|||
|
||||
### :sparkles: New features
|
||||
|
||||
- Fix clickable area of Penptot logo in the viewer [Taiga #7988](https://tree.taiga.io/project/penpot/issue/7988)
|
||||
- Fix constraints dropdown when selecting multiple shapes [Taiga #7686](https://tree.taiga.io/project/penpot/issue/7686)
|
||||
- Improve auth process [Taiga #7094](https://tree.taiga.io/project/penpot/us/7094)
|
||||
- Add locking degrees increment (hold shift) on path edition [Taiga #7761](https://tree.taiga.io/project/penpot/issue/7761)
|
||||
- Persistence & Concurrent Edition Enhancements [Taiga #5657](https://tree.taiga.io/project/penpot/us/5657)
|
||||
- Allow library colors as recent colors [Taiga #7640](https://tree.taiga.io/project/penpot/issue/7640)
|
||||
- Missing scroll in viewmode comments [Taiga #7427](https://tree.taiga.io/project/penpot/issue/7427)
|
||||
- Comments in View mode should mimic the positioning behavior of the Workspace [Taiga #7346](https://tree.taiga.io/project/penpot/issue/7346)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix clickable area of Penptot logo in the viewer [Taiga #7988](https://tree.taiga.io/project/penpot/issue/7988)
|
||||
- Fix constraints dropdown when selecting multiple shapes [Taiga #7686](https://tree.taiga.io/project/penpot/issue/7686)
|
||||
- Layout and scrollign fixes for the bottom palette [Taiga #7559](https://tree.taiga.io/project/penpot/issue/7559)
|
||||
- Fix expand libraries when search results are present [Taiga #7876](https://tree.taiga.io/project/penpot/issue/7876)
|
||||
- Fix color palette default library [Taiga #8029](https://tree.taiga.io/project/penpot/issue/8029)
|
||||
|
@ -39,6 +41,9 @@
|
|||
- Fix "Share prototypes" modal remains open [Taiga #7442](https://tree.taiga.io/project/penpot/issue/7442)
|
||||
- Fix "Components visibility and opacity" [#4694](https://github.com/penpot/penpot/issues/4694)
|
||||
- Fix "Attribute overrides in copies are not exported in zip file" [Taiga #8072](https://tree.taiga.io/project/penpot/issue/8072)
|
||||
- Fix group not automatically selected in the Layers panel after creation [Taiga #8078](https://tree.taiga.io/project/penpot/issue/8078)
|
||||
- Fix export boards loses opacity [Taiga #7592](https://tree.taiga.io/project/penpot/issue/7592)
|
||||
- Fix show in view mode and interactions workflow [Taiga #4711](https://github.com/penpot/penpot/pull/4711)
|
||||
|
||||
## 2.0.3
|
||||
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
(ns app.common.files.defaults)
|
||||
|
||||
(def version 48)
|
||||
(def version 49)
|
||||
|
|
|
@ -937,6 +937,26 @@
|
|||
(-> data
|
||||
(update :pages-index update-vals update-page))))
|
||||
|
||||
(defn migrate-up-49
|
||||
"Remove hide-in-viewer for shapes that are origin or destination of an interaction"
|
||||
[data]
|
||||
(letfn [(update-object [destinations object]
|
||||
(cond-> object
|
||||
(or (:interactions object)
|
||||
(contains? destinations (:id object)))
|
||||
(dissoc object :hide-in-viewer)))
|
||||
|
||||
(update-page [page]
|
||||
(let [destinations (->> page
|
||||
:objects
|
||||
(vals)
|
||||
(mapcat :interactions)
|
||||
(map :destination)
|
||||
(set))]
|
||||
(update page :objects update-vals (partial update-object destinations))))]
|
||||
|
||||
(update data :pages-index update-vals update-page)))
|
||||
|
||||
(def migrations
|
||||
"A vector of all applicable migrations"
|
||||
[{:id 2 :migrate-up migrate-up-2}
|
||||
|
@ -976,4 +996,5 @@
|
|||
{:id 45 :migrate-up migrate-up-45}
|
||||
{:id 46 :migrate-up migrate-up-46}
|
||||
{:id 47 :migrate-up migrate-up-47}
|
||||
{:id 48 :migrate-up migrate-up-48}])
|
||||
{:id 48 :migrate-up migrate-up-48}
|
||||
{:id 49 :migrate-up migrate-up-49}])
|
||||
|
|
|
@ -517,3 +517,16 @@
|
|||
{:with-objects? true})
|
||||
(pcb/reorder-grid-children [frame-id])))
|
||||
(pcb/remove-objects empty-parents))))
|
||||
|
||||
|
||||
(defn change-show-in-viewer [shape hide?]
|
||||
(cond-> (assoc shape :hide-in-viewer hide?)
|
||||
;; When a frame is no longer shown in view mode, it cannot have interactions
|
||||
hide?
|
||||
(dissoc :interactions)))
|
||||
|
||||
(defn add-new-interaction [shape interaction]
|
||||
(-> shape
|
||||
(update :interactions ctsi/add-interaction interaction)
|
||||
;; When a interaction is created, the frame must be shown in view mode
|
||||
(dissoc :hide-in-viewer)))
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.typographies-list :as cttl]
|
||||
[app.common.types.typography :as ctt]))
|
||||
|
||||
|
@ -99,3 +100,19 @@
|
|||
[file label & {:keys [] :as params}]
|
||||
(let [typography (sample-typography label params)]
|
||||
(ctf/update-file-data file #(cttl/add-typography % typography))))
|
||||
|
||||
(defn add-interaction
|
||||
[file origin-label dest-label]
|
||||
(let [page (thf/current-page file)
|
||||
origin (get-shape file origin-label)
|
||||
dest (get-shape file dest-label)
|
||||
interaction (-> ctsi/default-interaction
|
||||
(ctsi/set-destination (:id dest))
|
||||
(assoc :position-relative-to (:id origin)))
|
||||
interactions (ctsi/add-interaction (:interactions origin) interaction)]
|
||||
(ctf/update-file-data
|
||||
file
|
||||
(fn [file-data]
|
||||
(ctpl/update-page file-data
|
||||
(:id page)
|
||||
#(ctst/set-shape % (assoc origin :interactions interactions)))))))
|
||||
|
|
75
common/test/common_tests/logic/hide_in_viewer_test.cljc
Normal file
75
common/test/common_tests/logic/hide_in_viewer_test.cljc
Normal file
|
@ -0,0 +1,75 @@
|
|||
;; 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
|
||||
|
||||
(ns common-tests.logic.hide-in-viewer-test
|
||||
(:require
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.logic.shapes :as cls]
|
||||
[app.common.test-helpers.compositions :as tho]
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/use-fixtures :each thi/test-fixture)
|
||||
|
||||
|
||||
(t/deftest test-remove-show-in-view-mode-delete-interactions
|
||||
(let [;; ==== Setup
|
||||
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tho/add-frame :frame-dest)
|
||||
(tho/add-frame :frame-origin)
|
||||
(ths/add-interaction :frame-origin :frame-dest))
|
||||
|
||||
frame-origin (ths/get-shape file :frame-origin)
|
||||
|
||||
page (thf/current-page file)
|
||||
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil (:id page))
|
||||
(pcb/with-objects (:objects page))
|
||||
(pcb/update-shapes [(:id frame-origin)] #(cls/change-show-in-viewer % true)))
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
;; ==== Get
|
||||
frame-origin' (ths/get-shape file' :frame-origin)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (some? (:interactions frame-origin)))
|
||||
(t/is (nil? (:interactions frame-origin')))))
|
||||
|
||||
|
||||
|
||||
(t/deftest test-add-new-interaction-updates-show-in-view-mode
|
||||
(let [;; ==== Setup
|
||||
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tho/add-frame :frame-dest :hide-in-viewer true)
|
||||
(tho/add-frame :frame-origin :hide-in-viewer true))
|
||||
frame-dest (ths/get-shape file :frame-dest)
|
||||
frame-origin (ths/get-shape file :frame-origin)
|
||||
|
||||
page (thf/current-page file)
|
||||
|
||||
;; ==== Action
|
||||
new-interaction (-> ctsi/default-interaction
|
||||
(ctsi/set-destination (:id frame-dest))
|
||||
(assoc :position-relative-to (:id frame-dest)))
|
||||
|
||||
changes (-> (pcb/empty-changes nil (:id page))
|
||||
(pcb/with-objects (:objects page))
|
||||
(pcb/update-shapes [(:id frame-origin)] #(cls/add-new-interaction % new-interaction)))
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
;; ==== Get
|
||||
frame-origin' (ths/get-shape file' :frame-origin)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (true? (:hide-in-viewer frame-origin)))
|
||||
(t/is (nil? (:hide-in-viewer frame-origin')))))
|
File diff suppressed because one or more lines are too long
222
frontend/playwright/data/workspace/get-file-not-empty.json
Normal file
222
frontend/playwright/data/workspace/get-file-not-empty.json
Normal file
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"~:features":{
|
||||
"~#set":[
|
||||
"layout/grid",
|
||||
"styles/v2",
|
||||
"fdata/shape-data-type"
|
||||
]
|
||||
},
|
||||
"~:permissions":{
|
||||
"~:type":"~:membership",
|
||||
"~:is-owner":true,
|
||||
"~:is-admin":true,
|
||||
"~:can-edit":true,
|
||||
"~:can-read":true,
|
||||
"~:is-logged":true
|
||||
},
|
||||
"~:has-media-trimmed":false,
|
||||
"~:comment-thread-seqn":0,
|
||||
"~:name":"New File 14",
|
||||
"~:revn":1,
|
||||
"~:modified-at":"~m1718088151182",
|
||||
"~:id":"~u6191cd35-bb1f-81f7-8004-7cc63d087374",
|
||||
"~:is-shared":false,
|
||||
"~:version":48,
|
||||
"~:project-id":"~u4dc640b0-5cbf-11ec-a7c5-91e9eb4f238d",
|
||||
"~:created-at":"~m1718088142886",
|
||||
"~:data":{
|
||||
"~:pages":[
|
||||
"~u6191cd35-bb1f-81f7-8004-7cc63d087375"
|
||||
],
|
||||
"~:pages-index":{
|
||||
"~u6191cd35-bb1f-81f7-8004-7cc63d087375":{
|
||||
"~:options":{
|
||||
|
||||
},
|
||||
"~:objects":{
|
||||
"~u00000000-0000-0000-0000-000000000000":{
|
||||
"~#shape":{
|
||||
"~:y":0,
|
||||
"~:hide-fill-on-export":false,
|
||||
"~:transform":{
|
||||
"~#matrix":{
|
||||
"~:a":1.0,
|
||||
"~:b":0.0,
|
||||
"~:c":0.0,
|
||||
"~:d":1.0,
|
||||
"~:e":0.0,
|
||||
"~:f":0.0
|
||||
}
|
||||
},
|
||||
"~:rotation":0,
|
||||
"~:name":"Root Frame",
|
||||
"~:width":0.01,
|
||||
"~:type":"~:frame",
|
||||
"~:points":[
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":0,
|
||||
"~:y":0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":0.01,
|
||||
"~:y":0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":0.01,
|
||||
"~:y":0.01
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":0,
|
||||
"~:y":0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:proportion-lock":false,
|
||||
"~:transform-inverse":{
|
||||
"~#matrix":{
|
||||
"~:a":1.0,
|
||||
"~:b":0.0,
|
||||
"~:c":0.0,
|
||||
"~:d":1.0,
|
||||
"~:e":0.0,
|
||||
"~:f":0.0
|
||||
}
|
||||
},
|
||||
"~:id":"~u00000000-0000-0000-0000-000000000000",
|
||||
"~:parent-id":"~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id":"~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes":[
|
||||
|
||||
],
|
||||
"~:x":0,
|
||||
"~:proportion":1.0,
|
||||
"~:selrect":{
|
||||
"~#rect":{
|
||||
"~:x":0,
|
||||
"~:y":0,
|
||||
"~:width":0.01,
|
||||
"~:height":0.01,
|
||||
"~:x1":0,
|
||||
"~:y1":0,
|
||||
"~:x2":0.01,
|
||||
"~:y2":0.01
|
||||
}
|
||||
},
|
||||
"~:fills":[
|
||||
{
|
||||
"~:fill-color":"#FFFFFF",
|
||||
"~:fill-opacity":1
|
||||
}
|
||||
],
|
||||
"~:flip-x":null,
|
||||
"~:height":0.01,
|
||||
"~:flip-y":null,
|
||||
"~:shapes":[
|
||||
"~u7c75e310-c3a2-80fd-8004-7cc641479aef"
|
||||
]
|
||||
}
|
||||
},
|
||||
"~u7c75e310-c3a2-80fd-8004-7cc641479aef":{
|
||||
"~#shape":{
|
||||
"~:y":436,
|
||||
"~:rx":0,
|
||||
"~:transform":{
|
||||
"~#matrix":{
|
||||
"~:a":1.0,
|
||||
"~:b":0.0,
|
||||
"~:c":0.0,
|
||||
"~:d":1.0,
|
||||
"~:e":0.0,
|
||||
"~:f":0.0
|
||||
}
|
||||
},
|
||||
"~:rotation":0,
|
||||
"~:grow-type":"~:fixed",
|
||||
"~:hide-in-viewer":false,
|
||||
"~:name":"Rectangle",
|
||||
"~:width":126.00000000000006,
|
||||
"~:type":"~:rect",
|
||||
"~:points":[
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":266,
|
||||
"~:y":436
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":392.00000000000006,
|
||||
"~:y":436
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":392.00000000000006,
|
||||
"~:y":570
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point":{
|
||||
"~:x":266,
|
||||
"~:y":570
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:proportion-lock":false,
|
||||
"~:transform-inverse":{
|
||||
"~#matrix":{
|
||||
"~:a":1.0,
|
||||
"~:b":0.0,
|
||||
"~:c":0.0,
|
||||
"~:d":1.0,
|
||||
"~:e":0.0,
|
||||
"~:f":0.0
|
||||
}
|
||||
},
|
||||
"~:id":"~u7c75e310-c3a2-80fd-8004-7cc641479aef",
|
||||
"~:parent-id":"~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id":"~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes":[
|
||||
|
||||
],
|
||||
"~:x":266,
|
||||
"~:proportion":1,
|
||||
"~:selrect":{
|
||||
"~#rect":{
|
||||
"~:x":266,
|
||||
"~:y":436,
|
||||
"~:width":126.00000000000006,
|
||||
"~:height":134,
|
||||
"~:x1":266,
|
||||
"~:y1":436,
|
||||
"~:x2":392.00000000000006,
|
||||
"~:y2":570
|
||||
}
|
||||
},
|
||||
"~:fills":[
|
||||
{
|
||||
"~:fill-color":"#B1B2B5",
|
||||
"~:fill-opacity":1
|
||||
}
|
||||
],
|
||||
"~:flip-x":null,
|
||||
"~:ry":0,
|
||||
"~:height":134,
|
||||
"~:flip-y":null
|
||||
}
|
||||
}
|
||||
},
|
||||
"~:id":"~u6191cd35-bb1f-81f7-8004-7cc63d087375",
|
||||
"~:name":"Page 1"
|
||||
}
|
||||
},
|
||||
"~:id":"~u6191cd35-bb1f-81f7-8004-7cc63d087374"
|
||||
}
|
||||
}
|
10
frontend/playwright/data/workspace/get-thread-comments.json
Normal file
10
frontend/playwright/data/workspace/get-thread-comments.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -43,4 +43,18 @@ export class ViewerPage extends BaseWebSocketPage {
|
|||
async cleanUp() {
|
||||
await this.#ws.mockClose();
|
||||
}
|
||||
|
||||
async showComments(clickOptions = {}) {
|
||||
await this.page
|
||||
.getByRole("button", { name: "Comments (G C)" })
|
||||
.click(clickOptions);
|
||||
}
|
||||
|
||||
async showCommentsThread(number, clickOptions = {}) {
|
||||
await this.page
|
||||
.getByTestId("floating-thread-bubble")
|
||||
.filter({ hasText: number.toString() })
|
||||
.click(clickOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,11 @@ export class WorkspacePage extends BaseWebSocketPage {
|
|||
const layer = this.layers.getByTestId("layer-item").filter({ has: this.page.getByText(name) });
|
||||
await layer.getByRole("button").click(clickOptions);
|
||||
}
|
||||
|
||||
|
||||
async expectSelectedLayer(name) {
|
||||
await expect(this.layers.getByTestId("layer-row").filter({ has: this.page.getByText(name) })).toHaveClass(/selected/);
|
||||
}
|
||||
|
||||
async clickAssets(clickOptions = {}) {
|
||||
await this.assets.click(clickOptions);
|
||||
}
|
||||
|
|
34
frontend/playwright/ui/specs/viewer-comments.spec.js
Normal file
34
frontend/playwright/ui/specs/viewer-comments.spec.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { ViewerPage } from "../pages/ViewerPage";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await ViewerPage.init(page);
|
||||
});
|
||||
|
||||
const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1";
|
||||
const singleBoardPageId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb2";
|
||||
|
||||
const setupFileWithSingleBoard = async (viewer) => {
|
||||
await viewer.mockRPC(/get\-view\-only\-bundle\?/, "viewer/get-view-only-bundle-single-board.json");
|
||||
await viewer.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-not-empty.json");
|
||||
await viewer.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=*",
|
||||
"viewer/get-file-fragment-single-board.json",
|
||||
);
|
||||
await viewer.mockRPC("get-comments?thread-id=*", "workspace/get-thread-comments.json");
|
||||
await viewer.mockRPC("update-comment-thread-status", "workspace/update-comment-thread-status.json");
|
||||
};
|
||||
|
||||
test("Comment is shown with scroll and valid position", async ({ page }) => {
|
||||
const viewer = new ViewerPage(page);
|
||||
await viewer.setupLoggedInUser();
|
||||
await setupFileWithSingleBoard(viewer);
|
||||
|
||||
await viewer.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId });
|
||||
await viewer.showComments();
|
||||
await viewer.showCommentsThread(1);
|
||||
await expect(viewer.page.getByRole("textbox", { name: "Reply" })).toBeVisible();
|
||||
await viewer.showCommentsThread(1);
|
||||
await viewer.showCommentsThread(2);
|
||||
await expect(viewer.page.getByRole("textbox", { name: "Reply" })).toBeVisible();
|
||||
});
|
|
@ -66,3 +66,19 @@ test("User adds a library and its automatically selected in the color palette",
|
|||
|
||||
await expect(workspacePage.palette.getByText('There are no color styles in your library yet')).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
test("User makes a group", async ({ page }) => {
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile();
|
||||
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json");
|
||||
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json");
|
||||
|
||||
await workspacePage.goToWorkspace({
|
||||
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
|
||||
pageId: "6191cd35-bb1f-81f7-8004-7cc63d087375"
|
||||
});
|
||||
await workspacePage.clickLeafLayer("Rectangle");
|
||||
await workspacePage.page.keyboard.press("ControlOrMeta+g");
|
||||
await workspacePage.expectSelectedLayer("Group");
|
||||
});
|
||||
|
|
BIN
frontend/resources/images/form/Design.png
Normal file
BIN
frontend/resources/images/form/Design.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 15 KiB |
BIN
frontend/resources/images/form/Prototype.png
Normal file
BIN
frontend/resources/images/form/Prototype.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1.2 MiB |
BIN
frontend/resources/images/form/components.png
Normal file
BIN
frontend/resources/images/form/components.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 213 KiB |
BIN
frontend/resources/images/form/design-and-dev.png
Normal file
BIN
frontend/resources/images/form/design-and-dev.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 243 KiB |
BIN
frontend/resources/images/form/templates.png
Normal file
BIN
frontend/resources/images/form/templates.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 253 KiB |
|
@ -291,9 +291,7 @@
|
|||
// INPUTS
|
||||
.input-base {
|
||||
@include removeInputStyle;
|
||||
@include bodySmallTypography;
|
||||
@include textEllipsis;
|
||||
// @include focusInput;
|
||||
height: $s-28;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
|
@ -326,7 +324,6 @@
|
|||
}
|
||||
|
||||
.input-element {
|
||||
@include bodySmallTypography;
|
||||
@include focusInput;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -372,6 +372,7 @@
|
|||
--pill-foreground-color: var(--color-foreground-primary);
|
||||
|
||||
--link-foreground-color: var(--color-accent-primary);
|
||||
--register-confirmation-color: var(--status-color-success-200);
|
||||
|
||||
--resize-area-background-color: var(--color-background-primary);
|
||||
--resize-area-border-color: var(--color-background-quaternary);
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [selected (wsh/lookup-selected state)]
|
||||
(rx/of (group-shapes nil selected))))))
|
||||
(rx/of (group-shapes nil selected :change-selection? true))))))
|
||||
|
||||
(defn ungroup-shapes
|
||||
[ids & {:keys [change-selection?] :or {change-selection? false}}]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.logic.shapes :as cls]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
|
@ -131,8 +132,7 @@
|
|||
(let [new-interaction (-> ctsi/default-interaction
|
||||
(ctsi/set-destination destination)
|
||||
(assoc :position-relative-to (:id shape)))]
|
||||
(update shape :interactions
|
||||
ctsi/add-interaction new-interaction)))))
|
||||
(cls/add-new-interaction shape new-interaction)))))
|
||||
(when (and (not (connected-frame? objects (:id frame)))
|
||||
(nil? flow))
|
||||
(rx/of (add-flow (:id frame))))))))))
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
(when cls
|
||||
(cond
|
||||
(true? v) cls
|
||||
(false? v) nil
|
||||
(false? v) ""
|
||||
:else `(if ~v ~cls ""))))))
|
||||
(interpose " ")))
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
[app.main.ui.frame-preview :as frame-preview]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.messages :as msgs]
|
||||
[app.main.ui.onboarding :refer [onboarding-modal]]
|
||||
[app.main.ui.onboarding.newsletter :refer [onboarding-newsletter]]
|
||||
[app.main.ui.onboarding.questions :refer [questions-modal]]
|
||||
[app.main.ui.onboarding.team-choice :refer [onboarding-team-modal]]
|
||||
[app.main.ui.releases :refer [release-notes-modal]]
|
||||
[app.main.ui.static :as static]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -96,19 +98,43 @@
|
|||
#_[:& app.main.ui.onboarding/onboarding-modal]
|
||||
#_[:& app.main.ui.onboarding.team-choice/onboarding-team-modal]
|
||||
(when-let [props (get profile :props)]
|
||||
(cond
|
||||
(and (not (:onboarding-viewed props))
|
||||
(contains? cf/flags :onboarding))
|
||||
[:& onboarding-modal {}]
|
||||
(let [show-question-modal?
|
||||
(and (contains? cf/flags :onboarding)
|
||||
(not (:onboarding-viewed props))
|
||||
(not (contains? props :onboarding-questions)))
|
||||
|
||||
(and (contains? cf/flags :onboarding)
|
||||
(:onboarding-viewed props)
|
||||
(not= (:release-notes-viewed props) (:main cf/version))
|
||||
(not= "0.0" (:main cf/version)))
|
||||
[:& release-notes-modal {:version (:main cf/version)}]))
|
||||
show-newsletter-modal?
|
||||
(and (contains? cf/flags :onboarding)
|
||||
(not (:onboarding-viewed props))
|
||||
(not (contains? props :newsletter-updates))
|
||||
(contains? props :onboarding-questions))
|
||||
|
||||
show-team-modal?
|
||||
(and (contains? cf/flags :onboarding)
|
||||
(not (:onboarding-viewed props))
|
||||
(not (contains? props :onboarding-team-id))
|
||||
(contains? props :newsletter-updates))
|
||||
|
||||
show-release-modal?
|
||||
(and (contains? cf/flags :onboarding)
|
||||
(:onboarding-viewed props)
|
||||
(not= (:release-notes-viewed props) (:main cf/version))
|
||||
(not= "0.0" (:main cf/version)))]
|
||||
|
||||
(cond
|
||||
show-question-modal?
|
||||
[:& questions-modal]
|
||||
|
||||
show-newsletter-modal?
|
||||
[:& onboarding-newsletter]
|
||||
|
||||
show-team-modal?
|
||||
[:& onboarding-team-modal]
|
||||
|
||||
show-release-modal?
|
||||
[:& release-notes-modal {:version (:main cf/version)}])))
|
||||
|
||||
[:& dashboard-page {:route route :profile profile}]]
|
||||
|
||||
:viewer
|
||||
(let [{:keys [query-params path-params]} route
|
||||
{:keys [index share-id section page-id interactions-mode frame-id]
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
{::mf/props :obj}
|
||||
[{:keys [route]}]
|
||||
(let [section (dm/get-in route [:data :name])
|
||||
show-login-icon (and
|
||||
(not= section :auth-register-validate)
|
||||
(not= section :auth-register-success))
|
||||
params (:query-params route)
|
||||
error (:error params)]
|
||||
|
||||
|
@ -55,8 +58,9 @@
|
|||
(st/emit! (du/show-redirect-error error))))
|
||||
|
||||
[:main {:class (stl/css :auth-section)}
|
||||
[:h1 {:class (stl/css :logo-container)}
|
||||
[:a {:href "#/" :title "Penpot" :class (stl/css :logo-btn)} i/logo]]
|
||||
(when show-login-icon
|
||||
[:h1 {:class (stl/css :logo-container)}
|
||||
[:a {:href "#/" :title "Penpot" :class (stl/css :logo-btn)} i/logo]])
|
||||
[:div {:class (stl/css :login-illustration)}
|
||||
i/login-illustration]
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: $s-120;
|
||||
height: $s-96;
|
||||
margin-block-end: $s-52;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,14 +10,22 @@
|
|||
width: 100%;
|
||||
padding-block-end: 0;
|
||||
display: grid;
|
||||
gap: $s-24;
|
||||
gap: $s-12;
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-12;
|
||||
margin-top: $s-12;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-title-wrapper {
|
||||
width: 100%;
|
||||
padding-block-end: 0;
|
||||
display: grid;
|
||||
gap: $s-8;
|
||||
}
|
||||
|
||||
.separator {
|
||||
border-color: var(--modal-separator-backogrund-color);
|
||||
margin: 0;
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
[:& fm/input
|
||||
{:name :email
|
||||
:type "email"
|
||||
:label (tr "auth.email")
|
||||
:label (tr "auth.work-email")
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
:form form}
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:name :email
|
||||
:label (tr "auth.email")
|
||||
:label (tr "auth.work-email")
|
||||
:type "text"
|
||||
:class (stl/css :form-field)}]]
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:type "text"
|
||||
:name :email
|
||||
:label (tr "auth.email")
|
||||
:label (tr "auth.work-email")
|
||||
:data-test "email-input"
|
||||
:show-success? true
|
||||
:class (stl/css :form-field)}]]
|
||||
|
@ -134,11 +134,11 @@
|
|||
(mf/defc register-page
|
||||
{::mf/props :obj}
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form-wrapper)}
|
||||
[:div {:class (stl/css :auth-form-wrapper :register-form)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "registration-title"} (tr "auth.register-title")]
|
||||
[:p {:class (stl/css :auth-tagline)}
|
||||
(tr "auth.login-tagline")]
|
||||
(tr "auth.register-tagline")]
|
||||
|
||||
(when (contains? cf/flags :demo-warning)
|
||||
[:& login/demo-warning])
|
||||
|
@ -229,11 +229,11 @@
|
|||
(mf/html
|
||||
[:& tr-html
|
||||
{:tag-name "div"
|
||||
:label "auth.terms-privacy-agreement-md"
|
||||
:label "auth.terms-and-privacy-agreement"
|
||||
:params [cf/terms-of-service-uri cf/privacy-policy-uri]}])]
|
||||
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
|
||||
[:& fm/input {:name :accept-terms-and-privacy
|
||||
:class "check-primary"
|
||||
:class (stl/css :checkbox-terms-and-privacy)
|
||||
:type "checkbox"
|
||||
:default-checked false
|
||||
:label terms-label}]]))
|
||||
|
@ -247,11 +247,12 @@
|
|||
(mf/defc register-validate-page
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form-wrapper)}
|
||||
[:h1 {:class (stl/css :auth-title)
|
||||
:data-test "register-title"} (tr "auth.register-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
|
||||
|
||||
[:hr {:class (stl/css :separator)}]
|
||||
[:h1 {:class (stl/css :logo-container)}
|
||||
[:a {:href "#/" :title "Penpot" :class (stl/css :logo-btn)} i/logo]]
|
||||
[:div {:class (stl/css :auth-title-wrapper)}
|
||||
[:h2 {:class (stl/css :auth-title)
|
||||
:data-test "register-title"} (tr "auth.register-account-title")]
|
||||
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-account-tagline")]]
|
||||
|
||||
[:& register-validate-form {:params params}]
|
||||
|
||||
|
@ -264,7 +265,11 @@
|
|||
(mf/defc register-success-page
|
||||
[{:keys [params]}]
|
||||
[:div {:class (stl/css :auth-form-wrapper :register-success)}
|
||||
[:div {:class (stl/css :notification-icon)} i/icon-verify]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
|
||||
[:h1 {:class (stl/css :logo-container)}
|
||||
[:a {:href "#/" :title "Penpot" :class (stl/css :logo-btn)} i/logo]]
|
||||
[:div {:class (stl/css :auth-title-wrapper)}
|
||||
[:h2 {:class (stl/css :auth-title)}
|
||||
(tr "auth.check-mail")]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]]
|
||||
[:div {:class (stl/css :notification-text-email)} (:email params "")]
|
||||
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]])
|
||||
|
|
|
@ -8,15 +8,24 @@
|
|||
@use "./common.scss";
|
||||
|
||||
.accept-terms-and-privacy-wrapper {
|
||||
margin: $s-16 0;
|
||||
:global(a) {
|
||||
color: $df-secondary;
|
||||
font-weight: $fw700;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-terms-and-privacy {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.register-form {
|
||||
gap: $s-24;
|
||||
}
|
||||
|
||||
.register-success {
|
||||
padding-bottom: $s-32;
|
||||
gap: $s-24;
|
||||
.auth-title {
|
||||
@include medTitleTipography;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
|
@ -30,9 +39,30 @@
|
|||
}
|
||||
}
|
||||
|
||||
.notification-text-email,
|
||||
.notification-text {
|
||||
font-size: $fs-16;
|
||||
color: var(--notification-foreground-color-default);
|
||||
margin-bottom: $s-16;
|
||||
@include bodyMediumTypography;
|
||||
color: var(--title-foreground-color);
|
||||
}
|
||||
|
||||
.notification-text-email {
|
||||
@include medTitleTipography;
|
||||
font-size: $fs-20;
|
||||
color: var(--register-confirmation-color);
|
||||
margin-inline: $s-36;
|
||||
}
|
||||
|
||||
.logo-btn {
|
||||
height: $s-40;
|
||||
svg {
|
||||
width: $s-120;
|
||||
height: $s-40;
|
||||
fill: var(--main-icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: $s-120;
|
||||
margin-block-end: $s-24;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@
|
|||
[:*
|
||||
[:div
|
||||
{:class (stl/css :floating-thread-bubble)
|
||||
:data-testid "floating-thread-bubble"
|
||||
:style {:top (str pos-y "px")
|
||||
:left (str pos-x "px")}
|
||||
:on-click dom/stop-propagation}
|
||||
|
@ -435,9 +436,9 @@
|
|||
[:* {:key (dm/str (:id item))}
|
||||
[:& comment-item {:comment item
|
||||
:users users
|
||||
:origin origin}]])
|
||||
[:div {:ref ref}]]
|
||||
[:& reply-form {:thread thread}]])))
|
||||
:origin origin}]])]
|
||||
[:& reply-form {:thread thread}]
|
||||
[:div {:ref ref}]])))
|
||||
|
||||
(defn use-buble
|
||||
[zoom {:keys [position frame-id]}]
|
||||
|
@ -558,6 +559,7 @@
|
|||
:on-pointer-move on-pointer-move*
|
||||
:on-click on-click*
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:data-testid "floating-thread-bubble"
|
||||
:class (stl/css-case
|
||||
:floating-thread-bubble true
|
||||
:resolved (:is-resolved thread)
|
||||
|
|
|
@ -236,6 +236,7 @@
|
|||
.reply-form {
|
||||
textarea {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
line-height: 1.45;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
[:*
|
||||
(cond
|
||||
(some? label)
|
||||
[:label {:class (stl/css-case :input-with-label (not is-checkbox?)
|
||||
[:label {:class (stl/css-case :input-with-label-form (not is-checkbox?)
|
||||
:input-label is-text?
|
||||
:radio-label is-radio?
|
||||
:checkbox-label is-checkbox?)
|
||||
|
@ -214,7 +214,7 @@
|
|||
[:span {:class (stl/css :hint)} hint])]))
|
||||
|
||||
(mf/defc select
|
||||
[{:keys [options disabled form default dropdown-class] :as props
|
||||
[{:keys [options disabled form default dropdown-class select-class] :as props
|
||||
:or {default ""}}]
|
||||
(let [input-name (get props :name)
|
||||
form (or form (mf/use-ctx form-ctx))
|
||||
|
@ -230,6 +230,7 @@
|
|||
{:default-value value
|
||||
:disabled disabled
|
||||
:options options
|
||||
:class select-class
|
||||
:dropdown-class dropdown-class
|
||||
:on-change handle-change}]]))
|
||||
|
||||
|
@ -297,6 +298,71 @@
|
|||
:value value'
|
||||
:checked checked?}]]))]))
|
||||
|
||||
(mf/defc image-radio-buttons
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [form (or (unchecked-get props "form")
|
||||
(mf/use-ctx form-ctx))
|
||||
name (unchecked-get props "name")
|
||||
image (unchecked-get props "image")
|
||||
img-height (unchecked-get props "img-height")
|
||||
img-width (unchecked-get props "img-width")
|
||||
current-value (or (dm/get-in @form [:data name] "")
|
||||
(unchecked-get props "value"))
|
||||
on-change (unchecked-get props "on-change")
|
||||
options (unchecked-get props "options")
|
||||
trim? (unchecked-get props "trim")
|
||||
class (unchecked-get props "class")
|
||||
encode-fn (d/nilv (unchecked-get props "encode-fn") identity)
|
||||
decode-fn (d/nilv (unchecked-get props "decode-fn") identity)
|
||||
|
||||
on-change'
|
||||
(mf/use-fn
|
||||
(mf/deps on-change form name)
|
||||
(fn [event]
|
||||
(let [value (-> event dom/get-target dom/get-value decode-fn)]
|
||||
(when (some? form)
|
||||
(swap! form assoc-in [:touched name] true)
|
||||
(fm/on-input-change form name value trim?))
|
||||
|
||||
(when (fn? on-change)
|
||||
(on-change name value)))))]
|
||||
|
||||
[:div {:class (if image
|
||||
class
|
||||
(dm/str class " " (stl/css :custom-radio)))}
|
||||
(for [{:keys [image icon value label area]} options]
|
||||
(let [icon? (some? icon)
|
||||
value' (encode-fn value)
|
||||
checked? (= value current-value)
|
||||
key (str/ffmt "%-%" (d/name name) (d/name value'))]
|
||||
|
||||
[:label {:for key
|
||||
:key key
|
||||
:style {:grid-area area}
|
||||
:class (stl/css-case :radio-label-image true
|
||||
:global/checked checked?)}
|
||||
(cond
|
||||
icon?
|
||||
[:span {:class (stl/css :icon-inside)
|
||||
:style {:height img-height
|
||||
:width img-width}} icon]
|
||||
|
||||
:else
|
||||
[:span {:style {:background-image (str/ffmt "url(%)" image)
|
||||
:height img-height
|
||||
:width img-width}
|
||||
:class (stl/css :image-inside)}])
|
||||
|
||||
[:span {:class (stl/css :image-text)} label]
|
||||
[:input {:on-change on-change'
|
||||
:type "radio"
|
||||
:class (stl/css :radio-input)
|
||||
:id key
|
||||
:name name
|
||||
:value value'
|
||||
:checked checked?}]]))]))
|
||||
|
||||
(mf/defc submit-button*
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-click children label form class name disabled] :as props}]
|
||||
|
@ -378,6 +444,7 @@
|
|||
:no-padding (pos? (count @items))
|
||||
:invalid (and (some? valid-item-fn)
|
||||
touched?
|
||||
(not (str/empty? @value))
|
||||
(not (valid-item-fn @value)))))
|
||||
|
||||
on-focus
|
||||
|
|
|
@ -38,10 +38,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.input-with-label {
|
||||
.input-with-label-form {
|
||||
@include flexColumn;
|
||||
gap: $s-8;
|
||||
@include bodySmallTypography;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
|
@ -55,6 +54,7 @@
|
|||
color: var(--input-foreground-color-active);
|
||||
margin-top: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 $s-8;
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
|||
border-radius: $br-8;
|
||||
}
|
||||
}
|
||||
|
||||
// Input autofill
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
|
@ -169,6 +170,10 @@
|
|||
border-color: var(--input-checkbox-border-color-hover);
|
||||
}
|
||||
}
|
||||
a {
|
||||
// Need for terms and conditions links on register checkbox
|
||||
color: var(--link-foreground-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +372,7 @@
|
|||
height: fit-content;
|
||||
border-radius: $br-8;
|
||||
padding: $s-8;
|
||||
color: var(--input-foreground-color);
|
||||
color: var(--input-foreground-color-rest);
|
||||
border: $s-1 solid transparent;
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
|
@ -393,14 +398,12 @@
|
|||
border-radius: $br-circle;
|
||||
}
|
||||
|
||||
.radio-label.with-image {
|
||||
.radio-label-image {
|
||||
@include smallTitleTipography;
|
||||
display: grid;
|
||||
grid-template-rows: auto auto 0px;
|
||||
justify-items: center;
|
||||
gap: 0;
|
||||
height: $s-116;
|
||||
width: $s-92;
|
||||
border-radius: $br-8;
|
||||
margin: 0;
|
||||
border: 1px solid var(--color-background-tertiary);
|
||||
|
@ -413,22 +416,29 @@
|
|||
outline: none;
|
||||
border: $s-1 solid var(--input-border-color-active);
|
||||
}
|
||||
.image-text {
|
||||
color: var(--input-foreground-color-rest);
|
||||
display: grid;
|
||||
align-self: center;
|
||||
margin-bottom: $s-16;
|
||||
padding-inline: $s-8;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.image-inside {
|
||||
width: $s-60;
|
||||
height: $s-48;
|
||||
background-size: $s-48;
|
||||
margin: $s-16;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.icon-inside {
|
||||
width: $s-60;
|
||||
height: $s-48;
|
||||
margin: $s-16;
|
||||
@include flexCenter;
|
||||
svg {
|
||||
width: $s-60;
|
||||
height: $s-48;
|
||||
width: 40px;
|
||||
height: 60px;
|
||||
stroke: var(--icon-foreground);
|
||||
fill: none;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
@include bodySmallTypography;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
}
|
||||
.file-name-edit {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.file-name-label {
|
||||
|
|
|
@ -540,5 +540,6 @@
|
|||
|
||||
.email-input {
|
||||
@extend .input-base;
|
||||
@include bodySmallTypography;
|
||||
height: auto;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
.group-name-input {
|
||||
@extend .input-element-label;
|
||||
@include bodySmallTypography;
|
||||
margin-bottom: $s-8;
|
||||
label {
|
||||
@include flexColumn;
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
}
|
||||
.input-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
;; 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
|
||||
|
||||
(ns app.main.ui.onboarding
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.onboarding.newsletter]
|
||||
[app.main.ui.onboarding.questions]
|
||||
[app.main.ui.onboarding.team-choice]
|
||||
[app.main.ui.onboarding.templates]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.timers :as tm]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; --- ONBOARDING LIGHTBOX
|
||||
|
||||
(defn send-event
|
||||
[event-name]
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name event-name
|
||||
::ev/origin "dashboard"})))
|
||||
|
||||
|
||||
(mf/defc onboarding-welcome
|
||||
[{:keys [next] :as props}]
|
||||
(let [go-next
|
||||
(fn []
|
||||
(send-event "onboarding-step1-continue")
|
||||
(next))]
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/welcomeilustration.svg"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
[:h1 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.welcome.title")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.welcome.desc1")]
|
||||
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://community.penpot.app/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-community-link")}
|
||||
(tr "onboarding-v2.welcome.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc2")]]
|
||||
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:href "https://help.penpot.app/contributing-guide/"
|
||||
:target "_blank" :on-click #(send-event "onboarding-contributing-link")}
|
||||
(tr "onboarding-v2.welcome.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.welcome.desc3")]]
|
||||
|
||||
[:button {:on-click go-next
|
||||
:class (stl/css :accept-btn)
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]))
|
||||
|
||||
(mf/defc onboarding-before-start
|
||||
[{:keys [next] :as props}]
|
||||
(let [go-next
|
||||
(fn []
|
||||
(send-event "onboarding-step2-continue")
|
||||
(next))]
|
||||
[:div {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/beforeyoustartilustration.svg"
|
||||
:border "0"
|
||||
:alt (tr "onboarding.welcome.alt")}]]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :release)}
|
||||
"Version " (:main cf/version)]
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-welcome"}
|
||||
(tr "onboarding-v2.before-start.title")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.before-start.desc1")]
|
||||
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://help.penpot.app/user-guide/"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-user-guide-link")}
|
||||
(tr "onboarding-v2.before-start.desc2.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc2")]]
|
||||
|
||||
[:div {:class (stl/css :text-wrapper)}
|
||||
[:div {:class (stl/css :property-title)}
|
||||
[:a {:class (stl/css :modal-link)
|
||||
:href "https://www.youtube.com/c/Penpot"
|
||||
:target "_blank"
|
||||
:on-click #(send-event "onboarding-video-tutorials-link")}
|
||||
(tr "onboarding-v2.before-start.desc3.title")]]
|
||||
[:div {:class (stl/css :property-description)}
|
||||
(tr "onboarding-v2.before-start.desc3")]]
|
||||
|
||||
|
||||
[:button {:on-click go-next
|
||||
:class (stl/css :accept-btn)
|
||||
:data-test "onboarding-next-btn"}
|
||||
(tr "labels.continue")]]]))
|
||||
|
||||
(mf/defc onboarding-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding}
|
||||
[_]
|
||||
(let [slide (mf/use-state :start)
|
||||
klass (mf/use-state "fadeInDown")
|
||||
|
||||
navigate
|
||||
(mf/use-fn #(reset! slide %))
|
||||
|
||||
skip
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (modal/hide)
|
||||
(du/mark-onboarding-as-viewed))
|
||||
(cond
|
||||
(contains? cf/flags :onboarding-questions)
|
||||
(modal/show! {:type :onboarding-questions})
|
||||
|
||||
(contains? cf/flags :onboarding-newsletter)
|
||||
(modal/show! {:type :onboarding-newsletter})
|
||||
|
||||
(contains? cf/flags :onboarding-team)
|
||||
(modal/show! {:type :onboarding-team}))))
|
||||
|
||||
onboarding-a-b-test? (cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
(mf/with-effect [@slide]
|
||||
(when (not= :start @slide)
|
||||
(reset! klass "fadeIn"))
|
||||
(let [sem (tm/schedule 300 #(reset! klass nil))]
|
||||
(fn []
|
||||
(reset! klass nil)
|
||||
(tm/dispose! sem))))
|
||||
[:div {:class (stl/css-case :modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div.animated {:class (dm/str @klass " " (stl/css :animated))}
|
||||
(case @slide
|
||||
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
|
||||
:opensource [:& onboarding-before-start {:next skip}])]]))
|
|
@ -1,86 +0,0 @@
|
|||
// 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";
|
||||
|
||||
.modal-overlay {
|
||||
@extend .modal-overlay-base;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
gap: $s-32;
|
||||
padding-inline: $s-100;
|
||||
padding-block-start: $s-100;
|
||||
padding-block-end: $s-72;
|
||||
margin: 0;
|
||||
width: $s-960;
|
||||
height: $s-632;
|
||||
max-width: $s-960;
|
||||
max-height: $s-632;
|
||||
}
|
||||
|
||||
.modal-left {
|
||||
width: $s-240;
|
||||
margin-block-end: $s-64;
|
||||
img {
|
||||
width: $s-240;
|
||||
height: 100%;
|
||||
border-radius: $br-8 0 0 $br-8;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-right {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: $s-40 auto auto auto $s-32;
|
||||
gap: $s-24;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.release {
|
||||
@include bodySmallTypography;
|
||||
position: absolute;
|
||||
top: calc(-1 * $s-28);
|
||||
right: 0;
|
||||
padding: $s-8;
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@include bigTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.modal-text,
|
||||
.property-description {
|
||||
@include bodyLargeTypography;
|
||||
margin: 0;
|
||||
color: var(--modal-text-foreground-color);
|
||||
}
|
||||
|
||||
.modal-link {
|
||||
@include bodyLargeTypography;
|
||||
color: var(--modal-link-foreground-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.text-wrapper {
|
||||
@include flexColumn;
|
||||
}
|
||||
|
||||
.property-title a {
|
||||
@include medTitleTipography;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
justify-self: flex-end;
|
||||
}
|
|
@ -8,39 +8,52 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.config :as cf]
|
||||
[app.main.data.events :as-alias ev]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc onboarding-newsletter
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-newsletter}
|
||||
[]
|
||||
(let [message (tr "onboarding.newsletter.acceptance-message")
|
||||
newsletter-updates (mf/use-state false)
|
||||
newsletter-news (mf/use-state false)
|
||||
toggle
|
||||
(mf/use-callback
|
||||
(fn [option]
|
||||
(swap! option not)))
|
||||
(let [state* (mf/use-state #(do {:newsletter-updates false
|
||||
:newsletter-news false}))
|
||||
state (deref state*)
|
||||
|
||||
on-change
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [attr (-> (dom/get-current-target event)
|
||||
(dom/get-data "attr")
|
||||
(keyword))]
|
||||
(swap! state* update attr not))))
|
||||
|
||||
accept
|
||||
(mf/use-callback
|
||||
(mf/deps @newsletter-updates @newsletter-news)
|
||||
on-next
|
||||
(mf/use-fn
|
||||
(mf/deps state)
|
||||
(fn []
|
||||
(st/emit! (when (or @newsletter-updates @newsletter-news)
|
||||
(msg/success message))
|
||||
(modal/show {:type :onboarding-team})
|
||||
(du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))
|
||||
onboarding-a-b-test? (cf/external-feature-flag "signup-background" "test")]
|
||||
(when (or (:newsletter-updates state)
|
||||
(:newsletter-news state))
|
||||
(st/emit! (msg/success (tr "onboarding.newsletter.acceptance-message"))))
|
||||
|
||||
(let [params (-> state
|
||||
(assoc ::ev/name "onboarding-step")
|
||||
(assoc :label "newsletter:subscriptions")
|
||||
(assoc :step 6))]
|
||||
(st/emit! (ptk/data-event ::ev/event params)
|
||||
(du/update-profile-props state)))))
|
||||
|
||||
onboarding-a-b-test?
|
||||
(cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
[:div {:class (stl/css-case
|
||||
:modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
|
||||
[:div {:class (stl/css-case :modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div.animated.fadeInDown {:class (stl/css :modal-container)}
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:img {:src "images/deco-newsletter.png"
|
||||
|
@ -50,30 +63,34 @@
|
|||
[:h2 {:class (stl/css :modal-title)
|
||||
:data-test "onboarding-newsletter-title"}
|
||||
(tr "onboarding.newsletter.title")]
|
||||
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.desc")]
|
||||
|
||||
|
||||
[:div {:class (stl/css :newsletter-options)}
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-updates"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-updates)}
|
||||
(when @newsletter-updates
|
||||
i/status-tick)]
|
||||
[:span {:class (stl/css-case :global/checked (:newsletter-updates state))}
|
||||
i/status-tick]
|
||||
|
||||
(tr "onboarding-v2.newsletter.updates")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-updates"
|
||||
:on-change #(toggle newsletter-updates)}]]]
|
||||
:data-attr "newsletter-updates"
|
||||
:value (:newsletter-updates state)
|
||||
:on-change on-change}]]]
|
||||
|
||||
[:div {:class (stl/css :input-wrapper)}
|
||||
[:label {:for "newsletter-news"}
|
||||
[:span {:class (stl/css-case :global/checked @newsletter-news)}
|
||||
(when @newsletter-news
|
||||
i/status-tick)]
|
||||
[:span {:class (stl/css-case :global/checked (:newsletter-news state))}
|
||||
i/status-tick]
|
||||
|
||||
(tr "onboarding-v2.newsletter.news")
|
||||
[:input {:type "checkbox"
|
||||
:id "newsletter-news"
|
||||
:on-change #(toggle newsletter-news)}]]]]
|
||||
:data-attr "newsletter-news"
|
||||
:value (:newsletter-news state)
|
||||
:on-change on-change}]]]]
|
||||
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy1")
|
||||
|
@ -84,5 +101,6 @@
|
|||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding-v2.newsletter.privacy2")]
|
||||
|
||||
[:button {:on-click accept
|
||||
:class (stl/css :accept-btn)} (tr "labels.continue")]]]]))
|
||||
[:button {:on-click on-next
|
||||
:class (stl/css :accept-btn)}
|
||||
(tr "labels.continue")]]]]))
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.events :as-alias ev]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
|
@ -19,223 +19,430 @@
|
|||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc step-container
|
||||
[{:keys [form step on-next on-prev children class] :as props}]
|
||||
{::mf/props :obj}
|
||||
[{:keys [form step on-next on-prev children class label]}]
|
||||
|
||||
[:& fm/form {:form form :on-submit on-next :class (dm/str class " " (stl/css :form-wrapper))}
|
||||
[:div {:class (stl/css :paginator)} (str/ffmt "%/4" step)]
|
||||
(let [on-next*
|
||||
(mf/use-fn
|
||||
(mf/deps on-next step label)
|
||||
(fn [form event]
|
||||
(let [params (-> (:clean-data @form)
|
||||
(assoc :label label)
|
||||
(assoc :step step)
|
||||
(assoc ::ev/name "onboarding-step"))]
|
||||
(st/emit! (ptk/data-event ::ev/event params))
|
||||
(on-next form event))))]
|
||||
|
||||
children
|
||||
[:& fm/form {:form form
|
||||
:on-submit on-next*
|
||||
:class (dm/str class " " (stl/css :form-wrapper))}
|
||||
[:div {:class (stl/css :paginator)} (str/ffmt "%/5" step)]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
children
|
||||
|
||||
(when on-prev
|
||||
[:button {:class (stl/css :prev-button)
|
||||
:on-click on-prev} (tr "questions.previous")])
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (if (< step 4) (tr "questions.next") (tr "questions.start"))
|
||||
:class (stl/css :next-button)}]]])
|
||||
(when (some? on-prev)
|
||||
[:button {:class (stl/css :prev-button)
|
||||
:on-click on-prev}
|
||||
(tr "questions.previous")])
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:label (if (< step 5)
|
||||
(tr "questions.next")
|
||||
(tr "questions.start"))
|
||||
:class (stl/css :next-button)}]]]))
|
||||
|
||||
(s/def ::questions-form-step-1
|
||||
(s/keys :req-un [::planning]))
|
||||
|
||||
(mf/defc step-1
|
||||
[{:keys [on-next form] :as props}]
|
||||
[:& step-container {:form form :step 1 :on-next on-next :class (stl/css :step-1)}
|
||||
[:img {:class (stl/css :header-image)
|
||||
:src "images/form/use-for-1.png" :alt (tr "questions.lets-get-started")}]
|
||||
[:h1 {:class (stl/css :modal-title)} (tr "questions.lets-get-started")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "questions.your-feedback-will-help-us")]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.questions-how-are-you-planning-to-use-penpot")]
|
||||
[:& fm/select
|
||||
{:options [{:label (tr "questions.select-option")
|
||||
:value "" :key "questions-how-are-you-planning-to-use-penpot"
|
||||
:disabled true}
|
||||
{:label (tr "questions.discover-more-about-penpot")
|
||||
:value "discover-more-about-penpot"
|
||||
:key "discover-more-about-penpot"}
|
||||
{:label (tr "questions.test-penpot-to-see-if-its-a-fit-for-team")
|
||||
:value "test-penpot-to-see-if-its-a-fit-for-team"
|
||||
:key "test-penpot-to-see-if-its-a-fit-for-team"}
|
||||
{:label (tr "questions.start-to-work-on-my-project")
|
||||
:value "start-to-work-on-my-project"
|
||||
:key "start-to-work-on-my-project"}
|
||||
{:label (tr "questions.get-the-code-from-my-team-project")
|
||||
:value "get-the-code-from-my-team-project"
|
||||
:key "get-the-code-from-my-team-project"}
|
||||
{:label (tr "questions.leave-feedback-for-my-team-project")
|
||||
:value "leave-feedback-for-my-team-project"
|
||||
:key "leave-feedback-for-my-team-project"}
|
||||
{:label (tr "questions.work-in-concept-ideas")
|
||||
:value "work-in-concept-ideas"
|
||||
:key "work-in-concept-ideas"}
|
||||
{:label (tr "questions.try-out-before-using-penpot-on-premise")
|
||||
:value "try-out-before-using-penpot-on-premise"
|
||||
:key "try-out-before-using-penpot-on-premise"}]
|
||||
:default ""
|
||||
:name :planning
|
||||
:dropdown-class (stl/css :question-dropdown)}]]])
|
||||
|
||||
(s/def ::questions-form-step-2
|
||||
(s/keys :req-un [::experience-branding-illustrations-marketing-pieces
|
||||
::experience-interface-design-visual-assets-design-systems
|
||||
::experience-interface-wireframes-user-journeys-flows-navigation-trees]))
|
||||
|
||||
(mf/defc step-2
|
||||
[{:keys [on-next on-prev form] :as props}]
|
||||
[:& step-container {:form form :step 2 :on-next on-next :on-prev on-prev :class (stl/css :step-2)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "questions.describe-your-experience-working-on")]
|
||||
|
||||
[:div {:class (stl/css-case :modal-question true
|
||||
:question-centered true)}
|
||||
[:div {:class (stl/css-case :modal-subtitle true
|
||||
:centered true)}
|
||||
(tr "branding-illustrations-marketing-pieces")]
|
||||
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
|
||||
{:label (tr "questions.some") :value "some"}
|
||||
{:label (tr "questions.a-lot") :value "a-lot"}]
|
||||
:name :experience-branding-illustrations-marketing-pieces
|
||||
:class (stl/css :radio-btns)}]]
|
||||
|
||||
[:div {:class (stl/css-case :modal-question true
|
||||
:question-centered true)}
|
||||
[:div {:class (stl/css-case :modal-subtitle true
|
||||
:centered true)}
|
||||
(tr "questions.interface-design-visual-assets-design-systems")]
|
||||
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
|
||||
{:label (tr "questions.some") :value "some"}
|
||||
{:label (tr "questions.a-lot") :value "a-lot"}]
|
||||
:name :experience-interface-design-visual-assets-design-systems
|
||||
:class (stl/css :radio-btns)}]]
|
||||
|
||||
[:div {:class (stl/css-case :modal-question true
|
||||
:question-centered true)}
|
||||
[:div {:class (stl/css-case :modal-subtitle true
|
||||
:centered true)}
|
||||
(tr "questions.wireframes-user-journeys-flows-navigation-trees")]
|
||||
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
|
||||
{:label (tr "questions.some") :value "some"}
|
||||
{:label (tr "questions.a-lot") :value "a-lot"}]
|
||||
:name :experience-interface-wireframes-user-journeys-flows-navigation-trees
|
||||
:class (stl/css :radio-btns)}]]])
|
||||
|
||||
(s/def ::questions-form-step-3
|
||||
(s/keys :req-un [::experience-design-tool]
|
||||
:opt-un [::experience-design-tool-other]))
|
||||
(s/keys :req-un [::planning
|
||||
::expected-use]
|
||||
:opt-un [::planning-other]))
|
||||
|
||||
(defn- step-1-form-validator
|
||||
[errors data]
|
||||
(let [planning (-> (:planning data) (str/trim))]
|
||||
(let [planning (:planning data)
|
||||
planning-other (:planning-other data)]
|
||||
(cond-> errors
|
||||
(= planning "")
|
||||
(and (= planning "other")
|
||||
(str/blank? planning-other))
|
||||
(assoc :planning-other {:code "missing"})
|
||||
|
||||
(not= planning "other")
|
||||
(assoc :planning-other nil)
|
||||
|
||||
(str/blank? planning)
|
||||
(assoc :planning {:code "missing"}))))
|
||||
|
||||
(mf/defc step-1
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next form]}]
|
||||
(let [use-options
|
||||
(mf/with-memo []
|
||||
(shuffle [{:label (tr "questions.use-work") :value "use-work"}
|
||||
{:label (tr "questions.use-education") :value "use-education"}
|
||||
{:label (tr "questions.use-personal") :value "use-personal"}]))
|
||||
|
||||
planning-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.select-option")
|
||||
:value "" :key "questions:what-brings-you-here"
|
||||
:disabled true}
|
||||
{:label (tr "questions.reasons.exploring")
|
||||
:value "discover-more-about-penpot"
|
||||
:key "discover-more-about-penpot"}
|
||||
{:label (tr "questions.reasons.fit")
|
||||
:value "test-penpot-to-see-if-its-a-fit-for-team"
|
||||
:key "test-penpot-to-see-if-its-a-fit-for-team"}
|
||||
{:label (tr "questions.reasons.alternative")
|
||||
:value "alternative-to-figma"
|
||||
:key "alternative-to-figma"}
|
||||
{:label (tr "questions.reasons.testing")
|
||||
:value "try-out-before-using-penpot-on-premise"
|
||||
:key "try-out-before-using-penpot-on-premise"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other"})))
|
||||
|
||||
current-planning
|
||||
(dm/get-in @form [:data :planning])]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 1
|
||||
:label "questions:about-you"
|
||||
:on-next on-next
|
||||
:class (stl/css :step-1)}
|
||||
|
||||
[:img {:class (stl/css :header-image)
|
||||
:src "images/form/use-for-1.png"
|
||||
:alt (tr "questions.lets-get-started")}]
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "questions.step1-title")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "questions.step1-subtitle")]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)}
|
||||
(tr "questions.step1-question1")]
|
||||
|
||||
[:& fm/radio-buttons {:options use-options
|
||||
:name :expected-use
|
||||
:class (stl/css :radio-btns)}]
|
||||
|
||||
[:h3 {:class (stl/css :modal-subtitle)}
|
||||
(tr "questions.step1-question2")]
|
||||
|
||||
[:& fm/select
|
||||
{:options planning-options
|
||||
:select-class (stl/css :select-class)
|
||||
:default ""
|
||||
:name :planning
|
||||
:dropdown-class (stl/css :question-dropdown)}]
|
||||
|
||||
(when (= current-planning "other")
|
||||
[:& fm/input {:name :planning-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "questions.other")
|
||||
:label ""}])]]))
|
||||
|
||||
(s/def ::questions-form-step-2
|
||||
(s/keys :req-un [::experience-design-tool]
|
||||
:opt-un [::experience-design-tool-other]))
|
||||
|
||||
(defn- step-2-form-validator
|
||||
[errors data]
|
||||
(let [experience (:experience-design-tool data)
|
||||
experience-other (:experience-design-tool-other data)]
|
||||
|
||||
(cond-> errors
|
||||
(and (= experience "other")
|
||||
(str/blank? experience-other))
|
||||
(assoc :experience-design-tool-other {:code "missing"})
|
||||
|
||||
(not= experience "other")
|
||||
(assoc :experience-design-tool-other nil))))
|
||||
|
||||
(mf/defc step-2
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next on-prev form]}]
|
||||
(let [design-tool-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.figma") :img-width "48px" :img-height "60px"
|
||||
:value "figma" :image "images/form/figma.png"}
|
||||
{:label (tr "questions.sketch") :img-width "48px" :img-height "60px"
|
||||
:value "sketch" :image "images/form/sketch.png"}
|
||||
{:label (tr "questions.adobe-xd") :img-width "48px" :img-height "60px"
|
||||
:value "adobe-xd" :image "images/form/adobe-xd.png"}
|
||||
{:label (tr "questions.canva") :img-width "48px" :img-height "60px"
|
||||
:value "canva" :image "images/form/canva.png"}
|
||||
{:label (tr "questions.invision") :img-width "48px" :img-height "60px"
|
||||
:value "invision" :image "images/form/invision.png"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other" :icon i/curve})))
|
||||
|
||||
current-experience
|
||||
(dm/get-in @form [:clean-data :experience-design-tool])
|
||||
|
||||
on-design-tool-change
|
||||
(mf/use-fn
|
||||
(mf/deps current-experience)
|
||||
(fn []
|
||||
(when (not= current-experience "other")
|
||||
(swap! form d/dissoc-in [:data :experience-design-tool-other])
|
||||
(swap! form d/dissoc-in [:errors :experience-design-tool-other]))))]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 2
|
||||
:label "questions:experience-design-tool"
|
||||
:on-next on-next
|
||||
:on-prev on-prev
|
||||
:class (stl/css :step-2)}
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "question.design-tool-more-used")]
|
||||
[:div {:class (stl/css :radio-wrapper)}
|
||||
[:& fm/image-radio-buttons {:options design-tool-options
|
||||
:img-width "48px"
|
||||
:img-height "60px"
|
||||
:name :experience-design-tool
|
||||
:image true
|
||||
:class (stl/css :image-radio)
|
||||
:on-change on-design-tool-change}]
|
||||
|
||||
(when (= current-experience "other")
|
||||
[:& fm/input {:name :experience-design-tool-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "questions.other")
|
||||
:label ""}])]]))
|
||||
|
||||
(s/def ::questions-form-step-3
|
||||
(s/keys :req-un [::team-size ::role ::responsability]
|
||||
:opt-un [::role-other ::responsability-other]))
|
||||
|
||||
(defn- step-3-form-validator
|
||||
[errors data]
|
||||
(let [experience-design-tool (:experience-design-tool data)
|
||||
experience-design-tool-other (-> (:experience-design-tool-other data) str/trim)]
|
||||
(let [role (:role data)
|
||||
role-other (:role-other data)
|
||||
responsability (:responsability data)
|
||||
responsability-other (:responsability-other data)]
|
||||
|
||||
(cond-> errors
|
||||
(and (= experience-design-tool "other") (= 0 (count experience-design-tool-other)))
|
||||
(assoc :experience-design-tool-other {:code "missing"}))))
|
||||
(and (= role "other")
|
||||
(str/blank? role-other))
|
||||
(assoc :role-other {:code "missing"})
|
||||
|
||||
(not= role "other")
|
||||
(assoc :role-other nil)
|
||||
|
||||
(and (= responsability "other")
|
||||
(str/blank? responsability-other))
|
||||
(assoc :responsability-other {:code "missing"})
|
||||
|
||||
(not= responsability "other")
|
||||
(assoc :responsability-other nil))))
|
||||
|
||||
(mf/defc step-3
|
||||
[{:keys [on-next on-prev form] :as props}]
|
||||
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])
|
||||
on-design-tool-change
|
||||
(fn [_ _]
|
||||
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])]
|
||||
(when (not= experience-design-tool "other")
|
||||
(do
|
||||
(swap! form d/dissoc-in [:data :experience-design-tool-other])
|
||||
(swap! form d/dissoc-in [:errors :experience-design-tool-other])))))]
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next on-prev form]}]
|
||||
(let [role-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.select-option") :value "" :key "role" :disabled true}
|
||||
{:label (tr "questions.work-type.ux") :value "designer" :key "designer"}
|
||||
{:label (tr "questions.work-type.dev") :value "developer" :key "developer"}
|
||||
{:label (tr "questions.work-type.student") :value "student-teacher" :key "student"}
|
||||
{:label (tr "questions.work-type.graphic") :value "graphic-design" :key "design"}
|
||||
{:label (tr "questions.work-type.marketing") :value "marketing" :key "marketing"}
|
||||
{:label (tr "questions.work-type.product") :value "manager" :key "manager"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other"})))
|
||||
|
||||
[:& step-container {:form form :step 3 :on-next on-next :on-prev on-prev :class (stl/css :step-3)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "question.design-tool-more-experienced-with")]
|
||||
[:div {:class (stl/css :radio-wrapper)}
|
||||
[:& fm/radio-buttons {:options [{:label (tr "questions.figma") :value "figma" :image "images/form/figma.png" :area "image1"}
|
||||
{:label (tr "questions.sketch") :value "sketch" :image "images/form/sketch.png" :area "image2"}
|
||||
{:label (tr "questions.adobe-xd") :value "adobe-xd" :image "images/form/adobe-xd.png" :area "image3"}
|
||||
{:label (tr "questions.canva") :value "canva" :image "images/form/canva.png" :area "image4"}
|
||||
{:label (tr "questions.invision") :value "invision" :image "images/form/invision.png" :area "image5"}
|
||||
{:label (tr "questions.never-used-one") :area "image6" :value "never-used-a-tool" :icon i/curve}
|
||||
{:label (tr "questions.other") :value "other" :area "other"}]
|
||||
:name :experience-design-tool
|
||||
:image true
|
||||
:class (stl/css :image-radio)
|
||||
:on-change on-design-tool-change}]
|
||||
responsability-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.select-option") :value "" :key "responsability" :disabled true}
|
||||
{:label (tr "questions.role.team-leader") :value "team-leader"}
|
||||
{:label (tr "questions.role.team-member") :value "team-member"}
|
||||
{:label (tr "questions.role.freelancer") :value "freelancer"}
|
||||
{:label (tr "questions.role.founder") :value "ceo-founder"}
|
||||
{:label (tr "questions.role.director") :value "director"}
|
||||
{:label (tr "questions.student-teacher") :value "student-teacher"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other"})))
|
||||
|
||||
[:& fm/input {:name :experience-design-tool-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "questions.other")
|
||||
:label ""
|
||||
:disabled (not= experience-design-tool "other")}]]]))
|
||||
|
||||
team-size-options
|
||||
(mf/with-memo []
|
||||
[{:label (tr "questions.select-option") :value "" :key "team-size" :disabled true}
|
||||
{:label (tr "questions.more-than-50") :value "more-than-50" :key "more-than-50"}
|
||||
{:label (tr "questions.31-50") :value "31-50" :key "31-50"}
|
||||
{:label (tr "questions.11-30") :value "11-30" :key "11-30"}
|
||||
{:label (tr "questions.2-10") :value "2-10" :key "2-10"}
|
||||
{:label (tr "questions.freelancer") :value "freelancer" :key "freelancer"}
|
||||
{:label (tr "questions.personal-project") :value "personal-project" :key "personal-project"}])
|
||||
|
||||
current-role
|
||||
(dm/get-in @form [:data :role])
|
||||
|
||||
current-responsability
|
||||
(dm/get-in @form [:data :responsability])]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 3
|
||||
:label "questions:about-your-job"
|
||||
:on-next on-next
|
||||
:on-prev on-prev
|
||||
:class (stl/css :step-3)}
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)} (tr "questions.step3-title")]
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.step3.question1")]
|
||||
[:& fm/select {:options role-options
|
||||
:select-class (stl/css :select-class)
|
||||
:default ""
|
||||
:name :role}]
|
||||
|
||||
(when (= current-role "other")
|
||||
[:& fm/input {:name :role-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "questions.other")
|
||||
:label ""}])]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.step3.question2")]
|
||||
[:& fm/select {:options responsability-options
|
||||
:select-class (stl/css :select-class)
|
||||
:default ""
|
||||
:name :responsability}]
|
||||
|
||||
(when (= current-responsability "other")
|
||||
[:& fm/input {:name :responsability-other
|
||||
:class (stl/css :input-spacing)
|
||||
:placeholder (tr "questions.other")
|
||||
:label ""}])]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.company-size")]
|
||||
[:& fm/select {:options team-size-options
|
||||
:default ""
|
||||
:select-class (stl/css :select-class)
|
||||
:name :team-size}]]]))
|
||||
|
||||
(s/def ::questions-form-step-4
|
||||
(s/keys :req-un [::team-size ::role]
|
||||
:opt-un [::role-other]))
|
||||
(s/keys :req-un [::start-with]
|
||||
:opt-un [::start-with-other]))
|
||||
|
||||
(defn- step-4-form-validator
|
||||
[errors data]
|
||||
(let [role (:role data)
|
||||
role-other (-> (:role-other data) str/trim)]
|
||||
(let [start (:start-with data)
|
||||
start-other (:start-with-other data)]
|
||||
(cond-> errors
|
||||
(and (= role "other") (= 0 (count role-other)))
|
||||
(assoc :role-other {:code "missing"}))))
|
||||
(and (= start "other")
|
||||
(str/blank? start-other))
|
||||
(assoc :start-with-other {:code "missing"})
|
||||
|
||||
(not= start "other")
|
||||
(assoc :start-with-other nil))))
|
||||
|
||||
(mf/defc step-4
|
||||
[{:keys [on-next on-prev form] :as props}]
|
||||
(let [role (dm/get-in @form [:data :role])
|
||||
on-role-change
|
||||
(fn [_ _]
|
||||
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])]
|
||||
(when (not= experience-design-tool "other")
|
||||
(do
|
||||
(swap! form d/dissoc-in [:data :role-other])
|
||||
(swap! form d/dissoc-in [:errors :role-other])))))]
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next on-prev form]}]
|
||||
(let [start-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.starting-ui") :value "ui" :image "images/form/Design.png"}
|
||||
{:label (tr "questions.starting-wireframing") :value "wireframing" :image "images/form/templates.png"}
|
||||
{:label (tr "questions.starting-prototyping") :value "prototyping" :image "images/form/Prototype.png"}
|
||||
{:label (tr "questions.starting-ds") :value "ds" :image "images/form/components.png"}
|
||||
{:label (tr "questions.starting-code") :value "code" :image "images/form/design-and-dev.png"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other" :icon i/curve})))
|
||||
|
||||
[:& step-container {:form form :step 4 :on-next on-next :on-prev on-prev :class (stl/css :step-4)}
|
||||
[:h1 {:class (stl/css :modal-title)} (tr "questions.role")]
|
||||
current-start (dm/get-in @form [:data :start-with])
|
||||
|
||||
on-start-change
|
||||
(mf/use-fn
|
||||
(mf/deps current-start)
|
||||
(fn [_ _]
|
||||
(when (not= current-start "other")
|
||||
(swap! form d/dissoc-in [:data :start-with-other])
|
||||
(swap! form d/dissoc-in [:errors :start-with-other]))))]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 4
|
||||
:label "questions:how-start"
|
||||
:on-next on-next
|
||||
:on-prev on-prev
|
||||
:class (stl/css :step-4)}
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)} (tr "questions.step4-title")]
|
||||
[:div {:class (stl/css :radio-wrapper)}
|
||||
[:& fm/radio-buttons {:options [{:label (tr "questions.designer") :value "designer"}
|
||||
{:label (tr "questions.developer") :value "developer"}
|
||||
{:label (tr "questions.manager") :value "manager"}
|
||||
{:label (tr "questions.founder") :value "founder"}
|
||||
{:label (tr "questions.marketing") :value "marketing"}
|
||||
{:label (tr "questions.student-teacher") :value "student-teacher"}
|
||||
{:label (tr "questions.other") :value "other"}]
|
||||
:name :role
|
||||
:on-change on-role-change}]
|
||||
[:& fm/input {:name :role-other
|
||||
:class (stl/css :input-spacing)
|
||||
:label ""
|
||||
:placeholder (tr "questions.other")
|
||||
:disabled (not= role "other")}]]
|
||||
[:& fm/image-radio-buttons {:options start-options
|
||||
:img-width "159px"
|
||||
:img-height "120px"
|
||||
:class (stl/css :image-radio)
|
||||
:name :start-with
|
||||
:on-change on-start-change}]
|
||||
|
||||
[:div {:class (stl/css :modal-question)}
|
||||
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.team-size")]
|
||||
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "team-size" :disabled true}
|
||||
{:label (tr "questions.more-than-50") :value "more-than-50" :key "more-than-50"}
|
||||
{:label (tr "questions.31-50") :value "31-50" :key "31-50"}
|
||||
{:label (tr "questions.11-30") :value "11-30" :key "11-30"}
|
||||
{:label (tr "questions.2-10") :value "2-10" :key "2-10"}
|
||||
{:label (tr "questions.freelancer") :value "freelancer" :key "freelancer"}
|
||||
{:label (tr "questions.personal-project") :value "personal-project" :key "personal-project"}]
|
||||
:default ""
|
||||
:name :team-size}]]]))
|
||||
(when (= current-start "other")
|
||||
[:& fm/input {:name :start-with-other
|
||||
:class (stl/css :input-spacing)
|
||||
:label ""
|
||||
:placeholder (tr "questions.other")}])]]))
|
||||
|
||||
;; NOTE: we don't register it on registry modal because we reference
|
||||
;; this modal directly on the ui namespace.
|
||||
(s/def ::questions-form-step-5
|
||||
(s/keys :req-un [::referer]
|
||||
:opt-un [::referer-other]))
|
||||
|
||||
(defn- step-5-form-validator
|
||||
[errors data]
|
||||
(let [referer (:referer data)
|
||||
referer-other (:referer-other data)]
|
||||
(cond-> errors
|
||||
(and (= referer "other")
|
||||
(str/blank? referer-other))
|
||||
(assoc :referer-other {:code "missing"})
|
||||
|
||||
(not= referer "other")
|
||||
(assoc :referer-other nil))))
|
||||
|
||||
(mf/defc step-5
|
||||
{::mf/props :obj}
|
||||
[{:keys [on-next on-prev form]}]
|
||||
(let [referer-options
|
||||
(mf/with-memo []
|
||||
(-> (shuffle [{:label (tr "questions.referer.youtube") :value "youtube"}
|
||||
{:label (tr "questions.referer.event") :value "event"}
|
||||
{:label (tr "questions.referer.search") :value "search"}
|
||||
{:label (tr "questions.referer.social") :value "social"}
|
||||
{:label (tr "questions.referer.article") :value "article"}])
|
||||
(conj {:label (tr "questions.other-short") :value "other"})))
|
||||
|
||||
current-referer
|
||||
(dm/get-in @form [:data :referer])
|
||||
|
||||
on-referer-change
|
||||
(mf/use-fn
|
||||
(mf/deps current-referer)
|
||||
(fn []
|
||||
(when (not= current-referer "other")
|
||||
(swap! form d/dissoc-in [:data :referer-other])
|
||||
(swap! form d/dissoc-in [:errors :referer-other]))))]
|
||||
|
||||
[:& step-container {:form form
|
||||
:step 5
|
||||
:label "questions:referer"
|
||||
:on-next on-next
|
||||
:on-prev on-prev
|
||||
:class (stl/css :step-5)}
|
||||
|
||||
[:h1 {:class (stl/css :modal-title)} (tr "questions.step5-title")]
|
||||
[:div {:class (stl/css :radio-wrapper)}
|
||||
[:& fm/radio-buttons {:options referer-options
|
||||
:class (stl/css :radio-btns)
|
||||
:name :referer
|
||||
:on-change on-referer-change}]
|
||||
(when (= current-referer "other")
|
||||
[:& fm/input {:name :referer-other
|
||||
:class (stl/css :input-spacing)
|
||||
:label ""
|
||||
:placeholder (tr "questions.other")}])]]))
|
||||
|
||||
(mf/defc questions-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-questions}
|
||||
[]
|
||||
(let [container (mf/use-ref)
|
||||
step (mf/use-state 1)
|
||||
|
@ -247,9 +454,12 @@
|
|||
:initial {}
|
||||
:validators [step-1-form-validator]
|
||||
:spec ::questions-form-step-1)
|
||||
|
||||
step-2-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-2-form-validator]
|
||||
:spec ::questions-form-step-2)
|
||||
|
||||
step-3-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-3-form-validator]
|
||||
|
@ -260,6 +470,11 @@
|
|||
:validators [step-4-form-validator]
|
||||
:spec ::questions-form-step-4)
|
||||
|
||||
step-5-form (fm/use-form
|
||||
:initial {}
|
||||
:validators [step-5-form-validator]
|
||||
:spec ::questions-form-step-5)
|
||||
|
||||
on-next
|
||||
(mf/use-fn
|
||||
(fn [form]
|
||||
|
@ -275,27 +490,22 @@
|
|||
(mf/use-fn
|
||||
(mf/deps @clean-data)
|
||||
(fn [form]
|
||||
(let [questionnaire (merge @clean-data (:clean-data @form))]
|
||||
(reset! clean-data questionnaire)
|
||||
(st/emit! (du/mark-questions-as-answered questionnaire))
|
||||
(let [data (merge @clean-data (:clean-data @form))]
|
||||
(reset! clean-data data)
|
||||
(st/emit! (du/mark-questions-as-answered data)))))
|
||||
|
||||
(cond
|
||||
(contains? cf/flags :onboarding-newsletter)
|
||||
(modal/show! {:type :onboarding-newsletter})
|
||||
onboarding-a-b-test?
|
||||
(cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
(contains? cf/flags :onboarding-team)
|
||||
(modal/show! {:type :onboarding-team})
|
||||
|
||||
:else
|
||||
(modal/hide!)))))
|
||||
onboarding-a-b-test? (cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
[:div {:class (stl/css-case :modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div {:class (stl/css-case
|
||||
:modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div {:class (stl/css :modal-container)
|
||||
:ref container}
|
||||
|
||||
(case @step
|
||||
1 [:& step-1 {:on-next on-next :on-prev on-prev :form step-1-form}]
|
||||
2 [:& step-2 {:on-next on-next :on-prev on-prev :form step-2-form}]
|
||||
3 [:& step-3 {:on-next on-next :on-prev on-prev :form step-3-form}]
|
||||
4 [:& step-4 {:on-next on-submit :on-prev on-prev :form step-4-form}])]]))
|
||||
4 [:& step-4 {:on-next on-next :on-prev on-prev :form step-4-form}]
|
||||
5 [:& step-5 {:on-next on-submit :on-prev on-prev :form step-5-form}])]]))
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
}
|
||||
|
||||
.modal-container {
|
||||
max-width: $s-744;
|
||||
max-width: $s-960;
|
||||
max-height: fit-content;
|
||||
width: $s-744;
|
||||
width: fit-content;
|
||||
padding-inline: $s-100;
|
||||
padding-block-start: $s-40;
|
||||
padding-block-end: $s-72;
|
||||
|
@ -47,15 +47,15 @@
|
|||
@extend .modal-cancel-btn;
|
||||
}
|
||||
|
||||
.radio-btns label,
|
||||
.select-class span {
|
||||
@include bodyMediumTypography;
|
||||
}
|
||||
|
||||
// STEP 1
|
||||
|
||||
// .step-1 {
|
||||
// max-height: $s-468;
|
||||
// height: $s-468;
|
||||
// }
|
||||
|
||||
.header-image {
|
||||
height: $s-112;
|
||||
height: $s-60;
|
||||
width: auto;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
@ -81,9 +81,15 @@
|
|||
}
|
||||
|
||||
// STEP-2
|
||||
|
||||
.step-1,
|
||||
.step-2,
|
||||
.step-3,
|
||||
.step-5 {
|
||||
max-width: $s-540;
|
||||
width: $s-540;
|
||||
}
|
||||
.step-2 {
|
||||
grid-template-rows: $s-20 auto auto auto auto $s-32;
|
||||
grid-template-rows: $s-20 auto auto $s-32;
|
||||
}
|
||||
|
||||
.modal-question {
|
||||
|
@ -103,36 +109,36 @@
|
|||
.radio-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: $s-8;
|
||||
gap: $s-16;
|
||||
}
|
||||
|
||||
// STEP-3
|
||||
.step-3 {
|
||||
grid-template-rows: $s-20 auto auto $s-32;
|
||||
grid-template-rows: $s-20 auto auto auto auto $s-32;
|
||||
}
|
||||
|
||||
.image-radio {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr $s-32;
|
||||
grid-template-columns: $s-88 $s-92 $s-92 $s-92 $s-88;
|
||||
grid-template-areas:
|
||||
". image1 image2 image3 ."
|
||||
". image4 image5 image6 ."
|
||||
"other other other other other";
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-columns: $s-92 $s-92 $s-92;
|
||||
row-gap: $s-16;
|
||||
column-gap: $s-24;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.input-spacing {
|
||||
height: $s-32;
|
||||
width: calc(100% - $s-24);
|
||||
margin-inline-start: $s-24;
|
||||
width: 100%;
|
||||
margin-block-end: $s-8;
|
||||
}
|
||||
|
||||
.input-spacing input {
|
||||
@include bodyMediumTypography;
|
||||
}
|
||||
|
||||
// STEP-4
|
||||
|
||||
.step-4 {
|
||||
grid-template-rows: $s-20 auto auto auto $s-32;
|
||||
grid-template-rows: $s-20 auto auto $s-32;
|
||||
row-gap: $s-16;
|
||||
}
|
||||
|
|
|
@ -7,34 +7,29 @@
|
|||
(ns app.main.ui.onboarding.team-choice
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dmc]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cf]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.messages :as msg]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.router :as rt]
|
||||
[app.util.timers :as tm]
|
||||
[cljs.spec.alpha :as s]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(s/def ::name ::us/not-empty-string)
|
||||
(s/def ::team-form
|
||||
(s/keys :req-un [::name]))
|
||||
|
||||
(mf/defc team-modal-left
|
||||
(mf/defc left-sidebar
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[]
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
(tr "onboarding-v2.welcome.title")]
|
||||
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.team-definition")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
|
@ -61,99 +56,27 @@
|
|||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-5")]]]])
|
||||
|
||||
(mf/defc onboarding-team-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-team}
|
||||
[]
|
||||
(let [form (fm/use-form :spec ::team-form
|
||||
:initial {}
|
||||
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
(fn [form _]
|
||||
(let [tname (get-in @form [:clean-data :name])]
|
||||
(st/emit! (modal/show {:type :onboarding-team-invitations :name tname})
|
||||
(ptk/event ::ev/event {::ev/name "choose-team-name"
|
||||
::ev/origin "onboarding"
|
||||
:name tname
|
||||
:step 1})))))
|
||||
on-skip
|
||||
(fn []
|
||||
(tm/schedule 400 #(st/emit! (modal/hide)
|
||||
(ptk/event ::ev/event {::ev/name "create-team-later"
|
||||
::ev/origin "onboarding"
|
||||
:step 1}))))
|
||||
|
||||
teams (mf/deref refs/teams)
|
||||
onboarding-a-b-test? (cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
(mf/with-effect [teams]
|
||||
(when (> (count teams) 1)
|
||||
(st/emit! (modal/hide))))
|
||||
|
||||
(when (< (count teams) 2)
|
||||
[:div {:class (stl/css-case :modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:& team-modal-left]
|
||||
[:div {:class (stl/css :separator)}]
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :first-block)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form)
|
||||
:on-submit on-submit}
|
||||
|
||||
[:& fm/input {:type "text"
|
||||
:class (stl/css :team-name-input)
|
||||
:name :name
|
||||
:placeholder "Team name"
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:> fm/submit-button*
|
||||
{:class (stl/css :accept-button)
|
||||
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
|
||||
[:div {:class (stl/css :second-block)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :accept-button)
|
||||
:on-click on-skip}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
|
||||
|
||||
[:div {:class (stl/css :paginator)} "1/2"]]])))
|
||||
|
||||
(defn get-available-roles
|
||||
[]
|
||||
[{:value "editor" :label (tr "labels.editor")}
|
||||
{:value "admin" :label (tr "labels.admin")}])
|
||||
|
||||
(s/def ::emails (s/and ::us/set-of-valid-emails))
|
||||
(s/def ::role ::us/keyword)
|
||||
(s/def ::invite-form
|
||||
(s/keys :req-un [::role ::emails]))
|
||||
|
||||
;; This is the final step of team creation, consists in provide a
|
||||
;; shortcut for invite users.
|
||||
(defn- get-available-roles
|
||||
[]
|
||||
[{:value "editor" :label (tr "labels.editor")}
|
||||
{:value "admin" :label (tr "labels.admin")}])
|
||||
|
||||
(mf/defc team-form-step-2
|
||||
{::mf/props :obj}
|
||||
[{:keys [name on-back]}]
|
||||
(let [initial (mf/use-memo
|
||||
#(do {:role "editor"
|
||||
:name name}))
|
||||
|
||||
(mf/defc onboarding-team-invitations-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :onboarding-team-invitations
|
||||
::mf/props :obj}
|
||||
[{:keys [name]}]
|
||||
(let [initial (mf/use-memo (constantly
|
||||
{:role "editor"
|
||||
:name name}))
|
||||
form (fm/use-form :spec ::invite-form
|
||||
:initial initial)
|
||||
|
||||
params (:clean-data @form)
|
||||
emails (:emails params)
|
||||
|
||||
|
@ -161,51 +84,48 @@
|
|||
|
||||
on-success
|
||||
(mf/use-fn
|
||||
(fn [_form response]
|
||||
(let [team-id (:id response)]
|
||||
(st/emit!
|
||||
(modal/hide)
|
||||
(rt/nav :dashboard-projects {:team-id team-id}))
|
||||
(tm/schedule 400 #(st/emit!
|
||||
(modal/hide))))))
|
||||
(fn [response]
|
||||
(let [team-id (:id response)]
|
||||
(st/emit! (du/update-profile-props {:onboarding-team-id team-id
|
||||
:onboarding-viewed true})
|
||||
(rt/nav :dashboard-projects {:team-id team-id})))))
|
||||
|
||||
on-error
|
||||
(mf/use-fn
|
||||
(fn [_form _cause]
|
||||
(st/emit! (msg/error "Error on creating team."))))
|
||||
(fn [_]
|
||||
(st/emit! (msg/error (tr "errors.generic")))))
|
||||
|
||||
;; The SKIP branch only creates the team, without invitations
|
||||
on-invite-later
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(let [mdata {:on-success (partial on-success form)
|
||||
:on-error (partial on-error form)}
|
||||
(fn [{:keys [name]}]
|
||||
(let [mdata {:on-success on-success
|
||||
:on-error on-error}
|
||||
params {:name name}]
|
||||
(st/emit! (dd/create-team (with-meta params mdata))
|
||||
(ptk/event ::ev/event {::ev/name "create-team-and-invite-later"
|
||||
::ev/origin "onboarding"
|
||||
:name name
|
||||
:step 2})))))
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite-later"
|
||||
:team-name name
|
||||
:step 7})
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-finish"})))))
|
||||
|
||||
;; The SUBMIT branch creates the team with the invitations
|
||||
on-invite-now
|
||||
(mf/use-fn
|
||||
(fn [form]
|
||||
(let [mdata {:on-success (partial on-success form)
|
||||
:on-error (partial on-error form)}
|
||||
params (:clean-data @form)
|
||||
emails (:emails params)]
|
||||
(fn [{:keys [name] :as params}]
|
||||
(let [mdata {:on-success on-success
|
||||
:on-error on-error}]
|
||||
|
||||
(st/emit! (if (> (count emails) 0)
|
||||
;; If the user is only inviting to itself we don't call to create-team-with-invitations
|
||||
(dd/create-team-with-invitations (with-meta params mdata))
|
||||
(dd/create-team (with-meta {:name name} mdata)))
|
||||
(ptk/event ::ev/event {::ev/name "create-team-and-send-invitations"
|
||||
::ev/origin "onboarding"
|
||||
:invites (count emails)
|
||||
:role (:role params)
|
||||
:name name
|
||||
:step 2})))))
|
||||
(st/emit! (dd/create-team-with-invitations (with-meta params mdata))
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite"
|
||||
:invites (count emails)
|
||||
:team-name name
|
||||
:role (:role params)
|
||||
:step 7})
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-finish"})))))
|
||||
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
|
@ -213,55 +133,146 @@
|
|||
(let [params (:clean-data @form)
|
||||
emails (:emails params)]
|
||||
(if (> (count emails) 0)
|
||||
(on-invite-now form)
|
||||
(on-invite-later form))
|
||||
(modal/hide!))))
|
||||
onboarding-a-b-test? (cf/external-feature-flag "signup-background" "test")]
|
||||
(on-invite-now params)
|
||||
(on-invite-later params)))))]
|
||||
|
||||
[:div {:class (stl/css-case :modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:& team-modal-left]
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-right-invitations)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)} (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form-invitations)
|
||||
:on-submit on-submit}
|
||||
[:div {:class (stl/css :role-select)}
|
||||
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
|
||||
[:div {:class (stl/css :separator)}]
|
||||
[:div {:class (stl/css :modal-right-invitations)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)} (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
[:div {:class (stl/css :invitation-row)}
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :back-button)
|
||||
:on-click on-back}
|
||||
(tr "labels.back")]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:class (stl/css :accept-button)
|
||||
:label (if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))}]]
|
||||
[:div {:class (stl/css :modal-hint)}
|
||||
"(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")"]]]
|
||||
|
||||
|
||||
[:div {:class (stl/css :paginator)} "2/2"]]))
|
||||
|
||||
(mf/defc team-form-step-1
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [on-submit]}]
|
||||
(let [validators (mf/with-memo []
|
||||
[(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
|
||||
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
|
||||
|
||||
form (fm/use-form
|
||||
:spec ::team-form
|
||||
:initial {}
|
||||
:validators validators)
|
||||
|
||||
on-submit*
|
||||
(mf/use-fn
|
||||
(fn [form]
|
||||
(let [name (dm/get-in @form [:clean-data :name])]
|
||||
|
||||
(st/emit! (ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:choice-team-name"
|
||||
:step 7}))
|
||||
(on-submit name))))
|
||||
|
||||
on-skip
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (du/update-profile-props {:onboarding-viewed true})
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:skip-team-creation"
|
||||
:step 7})
|
||||
(ptk/data-event ::ev/event
|
||||
{::ev/name "onboarding-finish"}))))]
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :first-block)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form-invitations)
|
||||
:on-submit on-submit}
|
||||
[:div {:class (stl/css :role-select)}
|
||||
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
:class (stl/css :modal-form)
|
||||
:on-submit on-submit*}
|
||||
|
||||
[:div {:class (stl/css :invitation-row)}
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:auto-focus? true
|
||||
:trim true
|
||||
:valid-item-fn us/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")
|
||||
:on-submit on-submit}]]
|
||||
[:& fm/input {:type "text"
|
||||
:class (stl/css :team-name-input)
|
||||
:name :name
|
||||
:placeholder "Team name"
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :back-button)
|
||||
:on-click #(st/emit! (modal/show {:type :onboarding-team})
|
||||
(ptk/event ::ev/event {::ev/name "invite-members-back"
|
||||
::ev/origin "onboarding"
|
||||
:name name
|
||||
:step 2}))}
|
||||
(tr "labels.back")]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:class (stl/css :accept-button)
|
||||
:label (if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))}]]
|
||||
[:div {:class (stl/css :modal-hint)}
|
||||
(dmc/str "(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")")]]]
|
||||
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
|
||||
[:div {:class (stl/css :second-block)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :accept-button)
|
||||
:on-click on-skip}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
|
||||
|
||||
[:div {:class (stl/css :paginator)} "1/2"]]))
|
||||
|
||||
(s/def ::name ::us/not-empty-string)
|
||||
(s/def ::team-form
|
||||
(s/keys :req-un [::name]))
|
||||
|
||||
(mf/defc onboarding-team-modal
|
||||
{::mf/props :obj}
|
||||
[]
|
||||
(let [name* (mf/use-state nil)
|
||||
name (deref name*)
|
||||
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
(fn [tname]
|
||||
(swap! name* (constantly tname))))
|
||||
|
||||
|
||||
[:div {:class (stl/css :paginator)} "2/2"]]]))
|
||||
on-back
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! name* (constantly nil))))
|
||||
|
||||
onboarding-a-b-test?
|
||||
(cf/external-feature-flag "signup-background" "test")]
|
||||
|
||||
[:div {:class (stl/css-case
|
||||
:modal-overlay true
|
||||
:onboarding-a-b-test onboarding-a-b-test?)}
|
||||
|
||||
[:div.animated.fadeIn {:class (stl/css :modal-container)}
|
||||
[:& left-sidebar]
|
||||
[:div {:class (stl/css :separator)}]
|
||||
(if name
|
||||
[:& team-form-step-2 {:name name :on-back on-back}]
|
||||
[:& team-form-step-1 {:on-submit on-submit}])]]))
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@
|
|||
|
||||
.custom-input-token {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
&:focus {
|
||||
|
|
|
@ -134,6 +134,8 @@
|
|||
page-id (:id page)
|
||||
file-id (:id file)
|
||||
frame-id (:id frame)
|
||||
vsize (-> (mf/deref refs/viewer-local)
|
||||
:viewport-size)
|
||||
|
||||
tpos-ref (mf/with-memo [page-id]
|
||||
(-> (l/in [:pages page-id :options :comment-threads-position])
|
||||
|
@ -216,6 +218,7 @@
|
|||
[:& cmt/thread-comments
|
||||
{:thread thread
|
||||
:position-modifier modifier1
|
||||
:viewport {:offset-x 0 :offset-y 0 :width (:width vsize) :height (:height vsize)}
|
||||
:users users
|
||||
:zoom zoom}])
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
|
||||
.suffix-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
|
||||
.input-text {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
color: var(--input-foreground-color-active);
|
||||
padding-left: $s-8;
|
||||
margin: 0;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
@include flexRow;
|
||||
.input-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-84;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
@ -26,6 +27,7 @@
|
|||
@include flexRow;
|
||||
.input-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-84;
|
||||
&.hex {
|
||||
width: $s-172;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
@include bodySmallTypography;
|
||||
label {
|
||||
text-transform: none;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
}
|
||||
.input-wrapper {
|
||||
@extend .input-with-label;
|
||||
@include bodySmallTypography;
|
||||
margin-bottom: $s-8;
|
||||
}
|
||||
.action-buttons {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
:ref dref
|
||||
:on-click on-select-shape
|
||||
:on-context-menu on-context-menu
|
||||
:data-testid "layer-row"
|
||||
:class (stl/css-case
|
||||
:layer-row true
|
||||
:highlight highlighted?
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
|
||||
.second-row {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-92;
|
||||
.label {
|
||||
padding-left: $s-8;
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
.suffix-input {
|
||||
grid-column: span 3;
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
}
|
||||
|
||||
.export-btn {
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
border-radius: 0 $br-8 $br-8 0;
|
||||
.numeric-input {
|
||||
@extend .input-base;
|
||||
@include bodySmallTypography;
|
||||
}
|
||||
}
|
||||
.editable-select-wrapper {
|
||||
|
@ -93,6 +94,7 @@
|
|||
border: $s-1 solid var(--input-border-color);
|
||||
.numeric-input {
|
||||
@extend .input-base;
|
||||
@include bodySmallTypography;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -196,6 +198,7 @@
|
|||
}
|
||||
.height {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon-text {
|
||||
padding-top: $s-1;
|
||||
|
@ -204,6 +207,7 @@
|
|||
.gutter,
|
||||
.margin {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon {
|
||||
&.rotated svg {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
.area-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: 100%;
|
||||
padding: $s-8;
|
||||
}
|
||||
|
@ -51,6 +52,7 @@
|
|||
|
||||
.coord-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
border-left: $s-1 solid var(--panel-background-color);
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
}
|
||||
.input-element-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
grid-area: content;
|
||||
}
|
||||
.buttons-wrapper {
|
||||
|
@ -319,6 +320,7 @@
|
|||
|
||||
.flow-input {
|
||||
@extend .input-base;
|
||||
@include bodySmallTypography;
|
||||
background-color: transparent;
|
||||
height: $s-28;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
}
|
||||
.input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-60;
|
||||
}
|
||||
.actions {
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
gap: $s-4;
|
||||
.column-gap {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
&.disabled {
|
||||
@extend .disabled-input;
|
||||
|
@ -91,6 +92,7 @@
|
|||
}
|
||||
.row-gap {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
&.disabled {
|
||||
@extend .disabled-input;
|
||||
|
@ -113,6 +115,7 @@
|
|||
|
||||
.padding-simple {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
max-width: $s-108;
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +127,7 @@
|
|||
|
||||
.padding-multiple {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
max-width: $s-108;
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +243,7 @@
|
|||
|
||||
.track-info-value {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
border-radius: 0;
|
||||
border-right: $s-1 solid var(--panel-background-color);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
.z-index-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-60;
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,7 @@
|
|||
.vertical-margin,
|
||||
.horizontal-margin {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +111,7 @@
|
|||
.left-margin,
|
||||
.right-margin {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
}
|
||||
|
||||
|
@ -127,6 +130,7 @@
|
|||
.layout-item-max-w,
|
||||
.layout-item-max-h {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon-text {
|
||||
justify-content: flex-start;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.logic.shapes :as cls]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.main.constants :refer [size-presets]]
|
||||
|
@ -325,16 +326,15 @@
|
|||
(fn [event]
|
||||
(let [value (-> event dom/get-target dom/checked?)
|
||||
undo-id (js/Symbol)]
|
||||
(do
|
||||
(st/emit! (dwu/start-undo-transaction undo-id)
|
||||
(dwsh/update-shapes ids (fn [shape] (assoc shape :hide-in-viewer (not value)))))
|
||||
(st/emit! (dwu/start-undo-transaction undo-id)
|
||||
(dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value)))))
|
||||
|
||||
(when-not value
|
||||
(when-not value
|
||||
;; when a frame is no longer shown in view mode, cannot have
|
||||
;; interactions that navigate to it.
|
||||
(apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids)))
|
||||
(apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids)))
|
||||
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id))))))]
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))]
|
||||
|
||||
(mf/use-layout-effect
|
||||
(mf/deps radius-mode @radius-multi?)
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
.height,
|
||||
.width {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon-text {
|
||||
padding-top: $s-1;
|
||||
|
@ -145,6 +146,7 @@
|
|||
.x-position,
|
||||
.y-position {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon-text {
|
||||
padding-top: $s-1;
|
||||
|
@ -163,6 +165,7 @@
|
|||
|
||||
.rotation {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
.icon-text {
|
||||
padding-top: $s-1;
|
||||
|
@ -181,6 +184,7 @@
|
|||
|
||||
.radius-1 {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-108;
|
||||
}
|
||||
|
||||
|
@ -190,6 +194,7 @@
|
|||
gap: $s-4;
|
||||
.small-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-52;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
.spread-input,
|
||||
.offset-y-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-60;
|
||||
min-width: $s-60;
|
||||
align-items: baseline;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
.attr-input {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-124;
|
||||
}
|
||||
|
||||
|
|
|
@ -308,6 +308,7 @@
|
|||
.line-height,
|
||||
.letter-spacing {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
.icon {
|
||||
@include flexCenter;
|
||||
width: $s-28;
|
||||
|
@ -339,6 +340,7 @@
|
|||
padding: $s-8;
|
||||
.numeric-input {
|
||||
@extend .input-base;
|
||||
@include bodySmallTypography;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
.color-name-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
@ -166,6 +167,7 @@
|
|||
|
||||
.opacity-element-wrapper {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-60;
|
||||
border-radius: 0 $br-8 $br-8 0;
|
||||
.opacity-input {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
@include flexRow;
|
||||
.stroke-width-input-element {
|
||||
@extend .input-element;
|
||||
@include bodySmallTypography;
|
||||
width: $s-60;
|
||||
}
|
||||
.select-wrapper {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.util.forms
|
||||
(:refer-clojure :exclude [uuid])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
|
@ -69,11 +70,15 @@
|
|||
(::s/problems (s/explain-data spec (:data state))))
|
||||
|
||||
errors (reduce interpret-problem {} problems)
|
||||
|
||||
|
||||
errors (reduce (fn [errors vf]
|
||||
(merge errors (vf errors (:data state))))
|
||||
errors
|
||||
validators)
|
||||
errors (merge errors (:errors state))]
|
||||
errors (merge (:errors state) errors)
|
||||
errors (d/without-nils errors)]
|
||||
|
||||
|
||||
(assoc state
|
||||
:errors errors
|
||||
|
|
|
@ -278,7 +278,6 @@
|
|||
old-id (parser/get-id node)
|
||||
interactions (->> (parser/parse-interactions node)
|
||||
(mapv #(update % :destination resolve)))
|
||||
|
||||
data (-> (parser/parse-data type node)
|
||||
(resolve-data-ids type context)
|
||||
(cond-> (some? old-id)
|
||||
|
|
|
@ -244,19 +244,22 @@
|
|||
(first))
|
||||
|
||||
;; The nodes with the "frame-background" class can have some anidation depending on the strokes they have
|
||||
g-nodes (find-all-nodes node :g)
|
||||
defs-nodes (flatten (map #(find-all-nodes % :defs) g-nodes))
|
||||
gg-nodes (flatten (map #(find-all-nodes % :g) g-nodes))
|
||||
g-nodes (find-all-nodes node :g)
|
||||
defs-nodes (flatten (map #(find-all-nodes % :defs) g-nodes))
|
||||
gg-nodes (flatten (map #(find-all-nodes % :g) g-nodes))
|
||||
|
||||
;; The first g node contains the opacity for frames
|
||||
main-g-node (first g-nodes)
|
||||
|
||||
rect-nodes (flatten [[(find-all-nodes node :rect)]
|
||||
(map #(find-all-nodes % #{:rect :path}) defs-nodes)
|
||||
(map #(find-all-nodes % #{:rect :path}) g-nodes)
|
||||
(map #(find-all-nodes % #{:rect :path}) gg-nodes)])
|
||||
svg-node (d/seek #(= "frame-background" (get-in % [:attrs :class])) rect-nodes)]
|
||||
rect-nodes (flatten [[(find-all-nodes node :rect)]
|
||||
(map #(find-all-nodes % #{:rect :path}) defs-nodes)
|
||||
(map #(find-all-nodes % #{:rect :path}) g-nodes)
|
||||
(map #(find-all-nodes % #{:rect :path}) gg-nodes)])
|
||||
svg-node (d/seek #(= "frame-background" (get-in % [:attrs :class])) rect-nodes)]
|
||||
(merge
|
||||
(add-attrs {} (:attrs frame-clip-rect-node))
|
||||
(add-attrs {} (:attrs svg-node))
|
||||
(add-attrs {} (:attrs main-g-node))
|
||||
node-attrs))
|
||||
|
||||
(= type :svg-raw)
|
||||
|
|
|
@ -36,11 +36,6 @@ msgstr "ترغب في التجربة فحسب؟"
|
|||
msgid "auth.demo-warning"
|
||||
msgstr "هذه خدمة تجريبية ، لا تستخدمها للعمل الحقيقي ، سيتم مسح المشاريع بشكل دوري."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "البريد الالكتروني"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "هل نسيت كلمة السر؟"
|
||||
|
@ -136,10 +131,6 @@ msgstr "لا تملك حساب بعد؟"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "إنشاء حساب"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "إنه مجاني ، مفتوح المصدر"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "إنشاء حساب"
|
||||
|
|
|
@ -35,10 +35,6 @@ msgstr ""
|
|||
"এটি একটি ডেমো সার্ভিস। প্রয়োজনীয় কোনো কাজে ব্যবহার করবেন না। কিছু সময় পর "
|
||||
"প্রজেক্টগুলো মুছে ফেলা হবে।"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "ইমেইল"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "পাসওয়ার্ড ভুলে গেছেন?"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Aquest és un servei de PROVA. NO L'UTILITZEU en treballs reals, ja que els "
|
||||
"projectes s'eliminaran periòdicament."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Correu electrònic"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Heu oblidat la contrasenya?"
|
||||
|
@ -139,10 +134,6 @@ msgstr "No teniu un compte?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Creeu un compte"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "És gratuït, és de codi obert"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Crea un compte"
|
||||
|
@ -154,12 +145,6 @@ msgstr "La solució de codi obert per a dissenyar i prototipar."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Condicions del servei"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"En crear un compte nou, accepteu les condicions del servei i la política de "
|
||||
"privadesa."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "S'ha enviat un correu de verificació a"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Toto je DEMO služba, NEPOUŽÍVEJTE ji pro skutečnou práci, projekty budou "
|
||||
"pravidelně mazány."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Email"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Zapomněli jste heslo?"
|
||||
|
@ -151,10 +146,6 @@ msgstr "Ještě nemáte účet?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Vytvořit účet"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Je to zdarma, je to open source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Vytvořit účet"
|
||||
|
@ -5120,4 +5111,4 @@ msgid "workspace.updates.update"
|
|||
msgstr "Aktualizace"
|
||||
|
||||
msgid "workspace.viewport.click-to-close-path"
|
||||
msgstr "Kliknutím zavřete cestu"
|
||||
msgstr "Kliknutím zavřete cestu"
|
|
@ -39,10 +39,6 @@ msgstr ""
|
|||
"Det her er en DEMO service, BRUG IKKE for rigtigt arbejde, projekterne vil "
|
||||
"blive slettet periodevis."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Email"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Glemt adgangskode?"
|
||||
|
@ -135,10 +131,6 @@ msgstr "Ingen konto?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Opret en konto"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Det er gratis, det er Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Opret en konto"
|
||||
|
@ -147,12 +139,6 @@ msgstr "Opret en konto"
|
|||
msgid "auth.sidebar-tagline"
|
||||
msgstr "Open-source løsningen for design og prototyping."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Når du opretter en ny konto, accepterer du vores servicevilkår og "
|
||||
"fortrolighedspolitik."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Vi har sendt en bekræftelsesmail til"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Das ist eine DEMO-VERSION, verwenden Sie es NICHT zum Arbeiten, die Projekte "
|
||||
"werden regelmäßig gelöscht."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Passwort vergessen?"
|
||||
|
@ -176,10 +171,6 @@ msgstr "Noch kein Konto?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Konto erstellen"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Kostenlos, es ist Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Konto erstellen"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Αυτή είναι μια υπηρεσία DEMO, ΜΗ ΧΡΗΣΙΜΟΠΟΙΕΙΤΕ για πραγματική εργασία, τα "
|
||||
"έργα θα σβήνονται περιοδικά."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Email"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Ξεχάσατε τον κωδικό;"
|
||||
|
@ -134,10 +129,6 @@ msgstr "Δεν έχετε λογαριασμό;"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Δημιουργία λογαριασμού"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Είναι δωρεάν, είναι Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Δημιουργία λογαριασμού"
|
||||
|
@ -146,12 +137,6 @@ msgstr "Δημιουργία λογαριασμού"
|
|||
msgid "auth.sidebar-tagline"
|
||||
msgstr "Η λύση ανοιχτού κώδικα για σχεδιασμό και πρωτότυπο."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Δημιουργώντας έναν νέο λογαριασμό, αποδέχεστε τους όρους παροχής υπηρεσιών "
|
||||
"και την πολιτική απορρήτου."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Εχουμε στείλει ενα mail επαλήθευσης "
|
||||
|
|
|
@ -38,8 +38,8 @@ msgstr ""
|
|||
"periodically wiped."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Email"
|
||||
msgid "auth.work-email"
|
||||
msgstr "Work email"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
|
@ -55,7 +55,11 @@ msgstr "Log into my account"
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.login-here"
|
||||
msgstr "Login here"
|
||||
msgstr "Login here."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.check-mail"
|
||||
msgstr "Check your email"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.login-submit"
|
||||
|
@ -65,6 +69,14 @@ msgstr "Login"
|
|||
msgid "auth.login-tagline"
|
||||
msgstr "Penpot is the free open-source design tool for Design and Code collaboration"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.register-tagline"
|
||||
msgstr "With a free Penpot account, you can create unlimited teams and collaborate with other designers and developers on as many projects as you like. "
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.register-account-tagline"
|
||||
msgstr "Let us know what we should call you on the dashboard and in emails."
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.login-with-github-submit"
|
||||
msgstr "GitHub"
|
||||
|
@ -156,14 +168,14 @@ msgstr "No account yet?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Create an account"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "It's free, it's Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Create an account"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-account-title"
|
||||
msgstr "Your name"
|
||||
|
||||
#: src/app/main/ui/auth.cljs
|
||||
msgid "auth.sidebar-tagline"
|
||||
msgstr "The open-source solution for design and prototyping."
|
||||
|
@ -178,10 +190,9 @@ msgstr ""
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
#, markdown
|
||||
msgid "auth.terms-privacy-agreement-md"
|
||||
msgid "auth.terms-and-privacy-agreement"
|
||||
msgstr ""
|
||||
"When creating a new account, you agree to our [terms of service](%s) and "
|
||||
"[privacy policy](%s)."
|
||||
"I agree to the [terms of service](%s) and [privacy policy](%s)."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
|
@ -2382,24 +2393,52 @@ msgid "profile.recovery.go-to-login"
|
|||
msgstr "Go to login"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "question.design-tool-more-experienced-with"
|
||||
msgstr "Which is the design tool you have more experience with?"
|
||||
msgid "questions.step1-title"
|
||||
msgstr "Help us get to know you"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.11-30"
|
||||
msgstr "11-30"
|
||||
msgid "questions.step1-subtitle"
|
||||
msgstr "Let us know a bit about you to help us make Penpot work for you. Your answers will help us prioritize new features and point you in the right direction to get started."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.2-10"
|
||||
msgstr "2-10"
|
||||
msgid "questions.step1-question1"
|
||||
msgstr "What will you be using Penpot for?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
msgid "questions.use-work"
|
||||
msgstr "Work"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "A lot"
|
||||
msgid "questions.use-education"
|
||||
msgstr "Education"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.use-personal"
|
||||
msgstr "Personal"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step1-question2"
|
||||
msgstr "What brings you to Penpot today?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.exploring"
|
||||
msgstr "Just exploring"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.fit"
|
||||
msgstr "Reviewing whether Penpot is a good fit for my team"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.alternative"
|
||||
msgstr "Looking for an alternative to Figma, XD, etc"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.testing"
|
||||
msgstr "Testing before self-hosting"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "question.design-tool-more-used"
|
||||
msgstr "Which one of these tools do you use the most?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
|
@ -2409,148 +2448,182 @@ msgstr "Adobe XD"
|
|||
msgid "questions.canva"
|
||||
msgstr "Canva"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.describe-your-experience-working-on"
|
||||
msgstr "How would you best describe your experience working on..."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.designer"
|
||||
msgstr "Designer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.developer"
|
||||
msgstr "Developer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.discover-more-about-penpot"
|
||||
msgstr "Discover more about Penpot"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.figma"
|
||||
msgstr "Figma"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.founder"
|
||||
msgstr "Founder/VP"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.freelancer"
|
||||
msgstr "I'm a freelancer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.get-the-code-from-my-team-project"
|
||||
msgstr "Get the code from my team project "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.interface-design-visual-assets-design-systems"
|
||||
msgstr "... interface design, visual assets, design systems, etc."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.invision"
|
||||
msgstr "InVision"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.leave-feedback-for-my-team-project"
|
||||
msgstr "Leave feedback for my team project"
|
||||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "Let's get started!"
|
||||
msgid "questions.step3-title"
|
||||
msgstr "Tell us about your job"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.manager"
|
||||
msgstr "Product or Project manager"
|
||||
msgid "questions.step3.question1"
|
||||
msgstr "What kind of work do you do?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.marketing"
|
||||
msgid "questions.work-type.ux"
|
||||
msgstr "Product or UX design"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.dev"
|
||||
msgstr "Development"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.student"
|
||||
msgstr "student"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.graphic"
|
||||
msgstr "Graphic design"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.marketing"
|
||||
msgstr "Marketing"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.product"
|
||||
msgstr "Product Managment"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step3.question2"
|
||||
msgstr "What's your role?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.team-leader"
|
||||
msgstr "Team Leader"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.team-member"
|
||||
msgstr "Team member"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.freelancer"
|
||||
msgstr "Freelancer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.founder"
|
||||
msgstr "CEO or Founder"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.director"
|
||||
msgstr "Director"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.company-size"
|
||||
msgstr "What's the size of your company?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.more-than-50"
|
||||
msgstr "More than 50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.never-used-one"
|
||||
msgstr "None"
|
||||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.next"
|
||||
msgstr "Next"
|
||||
msgid "questions.11-30"
|
||||
msgstr "11-30"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "None"
|
||||
msgid "questions.2-10"
|
||||
msgstr "2-10"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Other (specify)"
|
||||
msgid "questions.freelancer"
|
||||
msgstr "I'm a freelancer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.personal-project"
|
||||
msgstr "I’m working in a personal project"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step4-title"
|
||||
msgstr "Where would you like to get started?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-ui"
|
||||
msgstr "Design the UI/UX of an app"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-wireframing"
|
||||
msgstr "Wireframing"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-prototyping"
|
||||
msgstr "Prototyping"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-ds"
|
||||
msgstr "Creating Desing Systems"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-code"
|
||||
msgstr "Generating real code designs"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step5-title"
|
||||
msgstr "How did you hear about Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.youtube"
|
||||
msgstr "YouTube"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.event"
|
||||
msgstr "Event"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.search"
|
||||
msgstr "Search Engine (Google, Yahoo, Bing)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.social"
|
||||
msgstr "Social Media (X, Linkedin, FB, etc)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.article"
|
||||
msgstr "Article (Blog, Post, Newsletter)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "Let's get started!"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.next"
|
||||
msgstr "Next"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Other (specify)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other-short"
|
||||
msgstr "Other"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.previous"
|
||||
msgstr "Previous"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.questions-how-are-you-planning-to-use-penpot"
|
||||
msgstr "How are you planning to use Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role"
|
||||
msgstr "What's your role?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.select-option"
|
||||
msgstr "Select option"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "Some"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "Start"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start-to-work-on-my-project"
|
||||
msgstr "Start to work on my project"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.student-teacher"
|
||||
msgstr "Student or teacher"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.team-size"
|
||||
msgstr "What's the size of your team?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.test-penpot-to-see-if-its-a-fit-for-team"
|
||||
msgstr "Test Penpot to see if it's a fit for team "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.try-out-before-using-penpot-on-premise"
|
||||
msgstr "Try out before using Penpot on-premise"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.wireframes-user-journeys-flows-navigation-trees"
|
||||
msgstr "... wireframes, user journeys & flows, navigation trees, etc."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-in-concept-ideas"
|
||||
msgstr "Work in concept ideas"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.your-feedback-will-help-us"
|
||||
msgstr ""
|
||||
"Your feedback will help us understand what your habits and preferences are "
|
||||
"so that we can keep making Penpot such a useful and enjoyable tool."
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs,
|
||||
msgid "settings.detach"
|
||||
msgstr "Detach"
|
||||
|
@ -2563,6 +2636,7 @@ msgstr "Mixed"
|
|||
msgid "settings.select-this-color"
|
||||
msgstr "Select items using this style"
|
||||
|
||||
|
||||
# SECTIONS
|
||||
msgid "shortcut-section.basics"
|
||||
msgstr "Basics"
|
||||
|
|
|
@ -39,9 +39,8 @@ msgstr ""
|
|||
"Este es un servicio de DEMOSTRACIÓN. NO USAR para trabajo real, los "
|
||||
"proyectos serán borrados periodicamente."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.work-email"
|
||||
msgstr "Correo electrónico"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
|
@ -58,7 +57,7 @@ msgstr "Entrar en mi cuenta"
|
|||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.login-here"
|
||||
msgstr "Inicia sesión aquí"
|
||||
msgstr "Inicia sesión aquí."
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.login-submit"
|
||||
|
@ -70,6 +69,14 @@ msgstr ""
|
|||
"Penpot es la herramienta de diseño libre y open-source para la colaboración "
|
||||
"entre Diseño y Código"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.register-tagline"
|
||||
msgstr "Con una cuenta gratuita de Penpot, puedes crear un número ilimitado de equipos y colaborar con otros diseñadores y desarrolladores en tantos proyectos como quieras."
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.register-account-tagline"
|
||||
msgstr "Cuéntanos cómo quieres que nos dirijamos a tí."
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.login-with-github-submit"
|
||||
msgstr "GitHub"
|
||||
|
@ -163,14 +170,14 @@ msgstr "¿No tienes una cuenta?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Crear una cuenta"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Es gratis, es Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Crear una cuenta"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-account-title"
|
||||
msgstr "Tu nombre"
|
||||
|
||||
#: src/app/main/ui/auth.cljs
|
||||
msgid "auth.sidebar-tagline"
|
||||
msgstr "La solución de código abierto para diseñar y prototipar."
|
||||
|
@ -190,10 +197,20 @@ msgstr ""
|
|||
"Al crear una nueva cuenta, aceptas nuestros [términos de servicio](%s) y "
|
||||
"[política de privacidad](%s)."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
#, markdown
|
||||
msgid "auth.terms-and-privacy-agreement"
|
||||
msgstr ""
|
||||
"Yo acepto los [términos de servicio](%s) y la [política de privacidad](%s)."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Hemos enviado un email de verificación a"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.check-mail"
|
||||
msgstr "Comprueba tu correo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "branding-illustrations-marketing-pieces"
|
||||
msgstr "diseño de marca, ilustraciones, piezas de marketing..."
|
||||
|
@ -2455,25 +2472,84 @@ msgstr "Penpot"
|
|||
msgid "profile.recovery.go-to-login"
|
||||
msgstr "Ir al login"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "question.design-tool-more-experienced-with"
|
||||
msgstr "¿Cuál es la herramienta de diseño con la que tienes más experiencia?"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.11-30"
|
||||
msgstr "11-30"
|
||||
msgid "questions.step1-title"
|
||||
msgstr "Ayúdanos a conocerte"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.2-10"
|
||||
msgstr "2-10"
|
||||
msgid "questions.step1-subtitle"
|
||||
msgstr "Cuéntanos un poco sobre tí para ayudarnos a que Penpot se adapte mejor a tí. Tus respuestas nos ayudarán a priorizar nuevas funcionalidades y a saber cómo podemos acompañarte mejor."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
msgid "questions.step1-question1"
|
||||
msgstr "¿Para qué utilizarás Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "Mucha"
|
||||
msgid "questions.use-work"
|
||||
msgstr "Trabajo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.use-education"
|
||||
msgstr "Educación"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.use-personal"
|
||||
msgstr "Personal"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step1-question2"
|
||||
msgstr "¿Qué te ha traído a Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.exploring"
|
||||
msgstr "Estoy echando un vistazo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.fit"
|
||||
msgstr "Averiguar si Penpot es una buena opción para mi equipo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.alternative"
|
||||
msgstr "Buscar una alternativa a Figma, XD, etc."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.reasons.testing"
|
||||
msgstr "Probar antes de self-hosting"
|
||||
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "question.design-tool-more-used"
|
||||
msgstr "¿Cuál de estas herramientas utilizas más?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
|
@ -2483,148 +2559,182 @@ msgstr "Adobe XD"
|
|||
msgid "questions.canva"
|
||||
msgstr "Canva"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.describe-your-experience-working-on"
|
||||
msgstr "Cuánta experiencia dirías que tienes trabajando con..."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.designer"
|
||||
msgstr "Diseño"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.developer"
|
||||
msgstr "Desarrollo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.discover-more-about-penpot"
|
||||
msgstr "Conocer Penpot mejor"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.figma"
|
||||
msgstr "Figma"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.founder"
|
||||
msgstr "Dirección"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.freelancer"
|
||||
msgstr "Soy freelancer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.get-the-code-from-my-team-project"
|
||||
msgstr "Obtener código de un proyecto"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.interface-design-visual-assets-design-systems"
|
||||
msgstr "diseño de interfaz, visual, sistemas de diseño..."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.invision"
|
||||
msgstr "InVision"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.leave-feedback-for-my-team-project"
|
||||
msgstr "Dejar comentarios en un proyecto"
|
||||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "¡Empecemos!"
|
||||
msgid "questions.step3-title"
|
||||
msgstr "Háblanos de tu trabajo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.manager"
|
||||
msgstr "Gestión de producto o proyecto"
|
||||
msgid "questions.step3.question1"
|
||||
msgstr "¿Qué tipo de trabajo haces?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.marketing"
|
||||
msgid "questions.work-type.ux"
|
||||
msgstr "Diseño de Producto o UX"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.dev"
|
||||
msgstr "Desarrollo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.student"
|
||||
msgstr "Estudiante"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.graphic"
|
||||
msgstr "Diseño gráfico"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.marketing"
|
||||
msgstr "Marketing"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-type.product"
|
||||
msgstr "Product Managment"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step3.question2"
|
||||
msgstr "¿Cuál es tu puesto?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.team-leader"
|
||||
msgstr "Líder de equipo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.team-member"
|
||||
msgstr "Miembro de equipo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.freelancer"
|
||||
msgstr "Autónomo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.founder"
|
||||
msgstr "CEO o Fundador"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role.director"
|
||||
msgstr "Director"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.company-size"
|
||||
msgstr "¿Cuál es el tamaño de tu empresa?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.more-than-50"
|
||||
msgstr "Más de 50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.never-used-one"
|
||||
msgstr "Ninguna"
|
||||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.next"
|
||||
msgstr "Siguiente"
|
||||
msgid "questions.11-30"
|
||||
msgstr "11-30"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "Ninguna"
|
||||
msgid "questions.2-10"
|
||||
msgstr "2-10"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Otra (especifica)"
|
||||
msgid "questions.freelancer"
|
||||
msgstr "Soy autónomo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.personal-project"
|
||||
msgstr "Estoy trabajando en un proyecto personal"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step4-title"
|
||||
msgstr "¿Por dónde te apetecería empezar?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-ui"
|
||||
msgstr "Diseñando el UX/UI de una aplicación"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-wireframing"
|
||||
msgstr "Wireframing"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-prototyping"
|
||||
msgstr "Prototipado"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-ds"
|
||||
msgstr "Creando sistemas de diseño"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.starting-code"
|
||||
msgstr "Generando código a partir de diseños"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.step5-title"
|
||||
msgstr "¿Cómo nos has descubierto?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.youtube"
|
||||
msgstr "YouTube"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.event"
|
||||
msgstr "Evento"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.search"
|
||||
msgstr "Buscador (Google, Yahoo, Bing)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.social"
|
||||
msgstr "Redes sociales (X, LinkedIn, FB, ect)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.referer.article"
|
||||
msgstr "Artículo (Blog, Post, Newsletter)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "¡Empecemos!"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.next"
|
||||
msgstr "Siguiente"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Otra (especifica)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other-short"
|
||||
msgstr "Otra"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.previous"
|
||||
msgstr "Anterior"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.questions-how-are-you-planning-to-use-penpot"
|
||||
msgstr "¿Qué uso piensas darle a Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role"
|
||||
msgstr "¿Cuál es tu rol?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.select-option"
|
||||
msgstr "Selecciona una opción"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "Alguna"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "Comenzar"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start-to-work-on-my-project"
|
||||
msgstr "Comenzar a trabajar en mi proyecto"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.student-teacher"
|
||||
msgstr "Estudiante o profesorado"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.team-size"
|
||||
msgstr "¿De qué tamaño es tu equipo?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.test-penpot-to-see-if-its-a-fit-for-team"
|
||||
msgstr "Valorar si Penpot es adecuado para mi equipo"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.try-out-before-using-penpot-on-premise"
|
||||
msgstr "Probar Penpot antes de usarlo en una instalación propia"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.wireframes-user-journeys-flows-navigation-trees"
|
||||
msgstr "prototipos, user journeys, flujos, árboles de navegación..."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-in-concept-ideas"
|
||||
msgstr "Conceptualizar ideas"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.your-feedback-will-help-us"
|
||||
msgstr ""
|
||||
"Tus respuestas nos ayudarán a entender tus hábitos y preferencias, lo que "
|
||||
"nos ayudará a continuar mejorando Penpot"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs,
|
||||
msgid "settings.detach"
|
||||
msgstr "Desacoplar"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Hau PROBAK EGITEKO zerbitzua da. EZ ERABILI benetako lana egiteko, hemengo "
|
||||
"proiektuak noizean behin ezabatu egingo dira."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Posta elektronikoa"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Pasahitza ahaztu duzu?"
|
||||
|
@ -139,10 +134,6 @@ msgstr "Ez duzu konturik?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Sortu kontua"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Doakoa da, Kode Irekia da"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Sortu kontua"
|
||||
|
@ -154,12 +145,6 @@ msgstr "Diseinuak eta prototipoak egiteko kode irekiko soluzioa."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Zerbitzuaren erabilpen-baldintzak"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Kontu berri bat sortzean, gure erabilpen-baldintzak eta pribatutasun "
|
||||
"politika onartzen dituzu."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Egiaztapen mezu bat bidali dugu helbide honetara"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"این یک سرویس آزمایشی است، برای کار واقعی استفاده نکنید، پروژهها به صورت "
|
||||
"دورهای پاک میشوند."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "ایمیل"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "کلمهعبور را فراموش کردهاید؟"
|
||||
|
@ -139,10 +134,6 @@ msgstr "هنوز حسابی ندارید؟"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "ایجاد حسابکاربری"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "رایگان است، منبعباز است"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "ایجاد حساب"
|
||||
|
@ -154,12 +145,6 @@ msgstr "راه حل منبع-باز برای طراحی و نمونهسازی
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "شرایط استفاده از خدمات"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"هنگام ایجاد یک حسابکاربری جدید، با شرایط خدمات و سیاست حفظ حریمخصوصی ما "
|
||||
"موافقت میکنید."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "ما یک ایمیل تأیید ارسال کردیم به"
|
||||
|
|
|
@ -39,10 +39,6 @@ msgstr ""
|
|||
"Tämä on DEMO versio, ÄLÄ KÄYTÄ oikeaan työhön, projektit tullaan määräajoin "
|
||||
"poistamaan."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Sähköposti"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Unohditko salasanasi?"
|
||||
|
@ -138,11 +134,6 @@ msgstr "Ei käyttäjää?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Luo uusi käyttäjä"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
#, fuzzy
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Se on ilmainen, sekä avointa lähdekoodia"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Luo uusi käyttäjä"
|
||||
|
@ -154,10 +145,6 @@ msgstr "Avoimen lähdekoodin ratkaisu suunnitteluun ja prototyyppien valmistukse
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Käyttöehdot"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr "Kun luot uuden käyttäjän, hyväksyt käyttöehdot ja tietosuojaselosteen."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Lähetimme vahvistussähköpostin osoitteeseen"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Hetta er ein ROYNDAR tænasta, IKKI BRÚKA til veruligt arbeiði, "
|
||||
"verkætlanirnar verða slettaðar regluliga."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Teldupostur"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Gloymt loyniorðið?"
|
||||
|
@ -137,10 +132,6 @@ msgstr "Onga konto enn?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Stovna konto"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Tað er ókeypis, tað Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Stovna eina konto"
|
||||
|
@ -148,12 +139,6 @@ msgstr "Stovna eina konto"
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Treytir"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Tá ið tú gert eina nýggja kontu, játtar tú tænastu- og privatlívs-treytir "
|
||||
"okkara."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Vit hava sent ein váttanar teldupost til"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Il s’agit d’un service de DÉMONSTRATION, NE L'UTILISEZ PAS pour du vrai "
|
||||
"travail, les projets seront périodiquement supprimés."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Adresse e‑mail"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Mot de passe oublié ?"
|
||||
|
@ -151,10 +146,6 @@ msgstr "Pas encore de compte ?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Créer un compte"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "C’est gratuit, c’est Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Créer un compte"
|
||||
|
@ -166,12 +157,6 @@ msgstr "La solution Open Source pour la conception et le prototypage."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Conditions générales d'utilisation"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"En créant un compte, vous acceptez nos conditions générales d'utilisation "
|
||||
"et notre politique de confidentialité."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Nous avons envoyé un e-mail de vérification à"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Este é un servizo de DEMOSTRACIÓN. NON O UTILICES para traballos reais, os "
|
||||
"proxectos eliminanse periódicamente."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Correo electrónico"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Esqueciches o teu contrasinal?"
|
||||
|
@ -139,10 +134,6 @@ msgstr "Ainda non tes unha conta?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Crea unha conta"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "É libre, é Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Crea unha conta"
|
||||
|
@ -154,12 +145,6 @@ msgstr "A solución de código aberto para deseñar e crear prototipos."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Condicións de servizo"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Ao crear unha nova conta, aceptas as nosas condicións de servizo e a "
|
||||
"política de privacidade."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Enviamos un correo electrónico de verificación a"
|
||||
|
|
|
@ -38,11 +38,6 @@ msgid "auth.demo-warning"
|
|||
msgstr ""
|
||||
"זה שירות ניסיוני, לא להשתמש בו לעבודה אמתית, המיזמים יימחקו מדי פעם בפעם."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "דוא״ל"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "שכחת סיסמה?"
|
||||
|
@ -170,10 +165,6 @@ msgstr "אין לך חשבון עדיין?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "יצירת חשבון"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "זה חינם, בקוד פתוח"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "יצירת חשבון"
|
||||
|
@ -2447,10 +2438,6 @@ msgstr "2-10"
|
|||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "הרבה מהם"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
msgstr "Adobe XD"
|
||||
|
@ -2459,22 +2446,6 @@ msgstr "Adobe XD"
|
|||
msgid "questions.canva"
|
||||
msgstr "Canva"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.describe-your-experience-working-on"
|
||||
msgstr "מה יתאר הכי טוב את אופן השימוש שלך…"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.designer"
|
||||
msgstr "עיצוב"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.developer"
|
||||
msgstr "פיתוח"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.discover-more-about-penpot"
|
||||
msgstr "היכרות מעמיקה יותר עם Penpot"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.figma"
|
||||
msgstr "Figma"
|
||||
|
@ -2507,14 +2478,6 @@ msgstr "להשאיר משוב למיזם הצוותי שלי"
|
|||
msgid "questions.lets-get-started"
|
||||
msgstr "מתחילים!"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.manager"
|
||||
msgstr "ניהול מוצר או מיזם"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.marketing"
|
||||
msgstr "שיווק"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.more-than-50"
|
||||
msgstr "גדול מ־50"
|
||||
|
@ -2527,10 +2490,6 @@ msgstr "אין"
|
|||
msgid "questions.next"
|
||||
msgstr "הבאה"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "כלום"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "אחר (נא לפרט)"
|
||||
|
@ -2543,14 +2502,6 @@ msgstr "זאת עבודה על מיזם פרטי"
|
|||
msgid "questions.previous"
|
||||
msgstr "הקודמת"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.questions-how-are-you-planning-to-use-penpot"
|
||||
msgstr "מהן התוכניות שלך בנוגע לשימוש ב־Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role"
|
||||
msgstr "מה התפקיד שלך?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.select-option"
|
||||
msgstr "בחירת אפשרות"
|
||||
|
@ -2559,10 +2510,6 @@ msgstr "בחירת אפשרות"
|
|||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "חלק מהם"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "התחלה"
|
||||
|
|
|
@ -38,11 +38,6 @@ msgstr ""
|
|||
"Ovo je DEMO usluga. NEMOJ KORISTITI za pravi rad. Projekti će se povremeno "
|
||||
"brisati."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Zaboravljena lozinka?"
|
||||
|
@ -138,10 +133,6 @@ msgstr "Još nemaš račun?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Stvori račun"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Besplatno je, Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Stvori račun"
|
||||
|
@ -153,12 +144,6 @@ msgstr "Open Source rješenje za dizajn i izradu prototipova."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Uvjeti pružanja usluge"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Kada kreiraš novi račun, slažeš se s našim uvjetima pružanja usluge i "
|
||||
"pravilima privatnosti."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Poslali smo e-mail za potvrdu na"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Ini layanan DEMO, JANGAN GUNAKAN untuk pekerjaan nyata, proyek-proyek ini "
|
||||
"akan di hapus secara berkala."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Surel"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Lupa kata sandi?"
|
||||
|
@ -164,10 +159,6 @@ msgstr "Belum punya akun?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Buat akun baru"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Gratis dan Sumber Terbuka"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Buat akun baru"
|
||||
|
@ -2428,10 +2419,6 @@ msgstr "2–10"
|
|||
msgid "questions.31-50"
|
||||
msgstr "31–50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "Banyak"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
msgstr "Adobe XD"
|
||||
|
@ -2461,42 +2448,18 @@ msgstr "Jelajahi lebih lanjut tentang Penpot"
|
|||
msgid "questions.figma"
|
||||
msgstr "Figma"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.founder"
|
||||
msgstr "Pendiri/VP"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.freelancer"
|
||||
msgstr "Saya seorang pekerja lepas"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.get-the-code-from-my-team-project"
|
||||
msgstr "Dapatkan kode dari proyek tim saya "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.interface-design-visual-assets-design-systems"
|
||||
msgstr "... desain antarmuka, aset visual, sistem desain, dll."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.invision"
|
||||
msgstr "InVision"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.leave-feedback-for-my-team-project"
|
||||
msgstr "Tinggalkan masukan untuk proyek tim saya"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "Mari kita mulai!"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.manager"
|
||||
msgstr "Pengelola Produk atau Proyek"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.marketing"
|
||||
msgstr "Pemasaran"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.more-than-50"
|
||||
msgstr "Lebih dari 50"
|
||||
|
@ -2505,10 +2468,6 @@ msgstr "Lebih dari 50"
|
|||
msgid "questions.next"
|
||||
msgstr "Berikutnya"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "Tidak ada"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Lainnya (jelaskan)"
|
||||
|
@ -2521,14 +2480,6 @@ msgstr "Saya mengerjakan proyek pribadi"
|
|||
msgid "questions.previous"
|
||||
msgstr "Sebelumnya"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.questions-how-are-you-planning-to-use-penpot"
|
||||
msgstr "Apa rencana Anda menggunakan Penpot?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role"
|
||||
msgstr "Apa peran Anda?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.select-option"
|
||||
msgstr "Pilih opsi"
|
||||
|
@ -2537,48 +2488,14 @@ msgstr "Pilih opsi"
|
|||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "Beberapa"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "Mulai"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start-to-work-on-my-project"
|
||||
msgstr "Mulai bekerja pada proyek saya"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.student-teacher"
|
||||
msgstr "Siswa atau Guru"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.team-size"
|
||||
msgstr "Seberapa besar tim Anda?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.test-penpot-to-see-if-its-a-fit-for-team"
|
||||
msgstr "Coba Penpot untuk tim Anda "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.try-out-before-using-penpot-on-premise"
|
||||
msgstr "Coba sebelum menggunakan Penpot on-premise"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.wireframes-user-journeys-flows-navigation-trees"
|
||||
msgstr "... gambar rangka, perjalanan & alur pengguna, pohon navigasi, dll."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-in-concept-ideas"
|
||||
msgstr "Bekerja dalam ide konsep"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.your-feedback-will-help-us"
|
||||
msgstr ""
|
||||
"Masukan Anda akan membantu kami mengerti kebiasaan dan preferensi Anda "
|
||||
"supaya kami dapat membuat Penpot sebuah alat yang berguna dan nyaman."
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs,
|
||||
msgid "settings.detach"
|
||||
msgstr "Copot"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Questo è un servizio di prova, non utilizzare per il lavoro reale, i "
|
||||
"progetti verranno eliminati periodicamente."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Indirizzo e-mail"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Hai dimenticato la password?"
|
||||
|
@ -135,10 +130,6 @@ msgstr "Non hai ancora un account?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Crea un account"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "È gratuito, è Open Source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Crea un account"
|
||||
|
@ -150,12 +141,6 @@ msgstr "La soluzione open source per il design e la prototipazione."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Condizioni di servizio"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Creando un account, accetti le condizioni generali di servizio e "
|
||||
"l'informativa sulla privacy."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Abbiamo inviato l'e-mail di verifica a"
|
||||
|
|
|
@ -35,10 +35,6 @@ msgstr "試してみませんか?"
|
|||
msgid "auth.demo-warning"
|
||||
msgstr "このサービスはデモ版です。実際の業務には使用しないでください。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "Eメール"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "パスワードを忘れましたか?"
|
||||
|
@ -134,10 +130,6 @@ msgstr "アカウントをお持ちでない方はこちら"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "アカウントを作成"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "フリーでオープンソースです"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "アカウントを作成"
|
||||
|
@ -149,10 +141,6 @@ msgstr "デザインとプロトタイピングのためのオープンソース
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "利用規約"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr "サービスに登録するには、利用規約とプライバシーポリシーに同意する必要があります。"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "認証メールを送信しました"
|
||||
|
|
|
@ -27,10 +27,6 @@ msgstr "데모 계정을 생성하세요"
|
|||
msgid "auth.create-demo-profile"
|
||||
msgstr "그냥 해볼까요?"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "이메일"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "비밀번호를 잊어버리셨나요?"
|
||||
|
|
|
@ -41,10 +41,6 @@ msgstr ""
|
|||
"Tai yra DEMONSTRACINĖ versija, NEKURKITE tikrų darbų, nes projektai "
|
||||
"periodiškai - šalinami."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "El. paštas"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Pamiršote slaptažodį?"
|
||||
|
@ -141,10 +137,6 @@ msgstr "Dar neturite paskyros?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Sukurti paskyrą"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Tai - nemokama, tai - atviras kodas"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Sukurti paskyrą"
|
||||
|
@ -156,12 +148,6 @@ msgstr "Atviro kodo dizaino ir prototipų kūrimo sprendimas."
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "Paslaugų teikimo sąlygos"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"Kurdami naują paskyrą sutinkate su mūsų paslaugų teikimo sąlygomis ir "
|
||||
"privatumo politika."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "Išsiuntėme patvirtinimo el. laišką adresu"
|
||||
|
|
|
@ -40,11 +40,6 @@ msgstr ""
|
|||
"Šis ir IZRĀDĪŠANAS pakalpojums, kas NAV IZMANTOJAMS īstam darbam, jo "
|
||||
"projekti ik pēc noteikta laika posma tiks izdzēsti."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "E-pasta adrese"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Aizmirsta parole?"
|
||||
|
@ -162,10 +157,6 @@ msgstr "Vēl nav konta?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Izveidot kontu"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Tas ir bezmaksas, tā ir atvērtā pirmkoda programmatūra"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Izveidot kontu"
|
||||
|
@ -2485,10 +2476,6 @@ msgstr "2-10"
|
|||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "Plaša"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
msgstr "Adobe XD"
|
||||
|
@ -2525,22 +2512,10 @@ msgstr "Dibinātājs/viceprezidents"
|
|||
msgid "questions.freelancer"
|
||||
msgstr "Esmu ārštātnieks(-ce)/Pašnodarbināts(-ā)"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.get-the-code-from-my-team-project"
|
||||
msgstr "Koda iegūšana no manas grupas projekta "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.interface-design-visual-assets-design-systems"
|
||||
msgstr "... saskarnes dizains, vizuālie līdzekļi, dizaina sistēmas utt."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.invision"
|
||||
msgstr "InVision"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.leave-feedback-for-my-team-project"
|
||||
msgstr "Atstāt atsauksmes par manas grupas projektu"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "Ķeramies pie darba!"
|
||||
|
@ -2565,10 +2540,6 @@ msgstr "Neviens"
|
|||
msgid "questions.next"
|
||||
msgstr "Nākamais"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "Nav"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Cits (jānorāda)"
|
||||
|
@ -2597,10 +2568,6 @@ msgstr "Atlasīt iespēju"
|
|||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "Nelielā"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "Sākt"
|
||||
|
|
|
@ -39,10 +39,6 @@ msgstr ""
|
|||
"ഇതൊരു ഡെമോ സേവനമാണ്, ഒരു യഥാർത്ഥ ജോലിക്ക് ഉപയോഗിക്കരുത്, പ്രൊജക്റ്റുകൾ "
|
||||
"നിശ്ചിതസമയങ്ങളിൽ മായ്ക്കപ്പെടും."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "ഇമെയിൽ"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "പാസ്വേഡ് മറന്നോ?"
|
||||
|
@ -138,10 +134,6 @@ msgstr "ഇതുവരെ അക്കൗണ്ട് ഇല്ലേ?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "അക്കൗണ്ട് സൃഷ്ടിക്കുക"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "ഇത് സൗജന്യമാണ്, ഇത് ഓപ്പൺ സോഴ്സാണ്"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "അക്കൗണ്ട് സൃഷ്ടിക്കുക"
|
||||
|
@ -153,12 +145,6 @@ msgstr "ഡിസൈനിങിനും പ്രോട്ടോടൈപ്
|
|||
msgid "auth.terms-of-service"
|
||||
msgstr "ഉപയോഗനിബന്ധനകൾ"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.terms-privacy-agreement"
|
||||
msgstr ""
|
||||
"ഒരു അക്കൗണ്ട് സൃഷ്ടിക്കുമ്പോൾ, നിങ്ങൾ ഞങ്ങളുടെ ഉപയോഗനിബന്ധനകളും "
|
||||
"സ്വകാര്യതാനയവും അംഗീകരിക്കുന്നു."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.verification-email-sent"
|
||||
msgstr "സാധൂകരിക്കാനുള്ള ഇമെയിൽ ഞങ്ങൾ അയച്ചിരിക്കുന്നു"
|
||||
|
|
|
@ -25,10 +25,6 @@ msgstr ""
|
|||
"Ini adalah perkhidmatan DEMO, JANGAN GUNAKAN untuk kerja sebenar, projek "
|
||||
"akan dipadam secara berkala."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "E-mel"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Lupa kata laluan?"
|
||||
|
|
|
@ -15,11 +15,6 @@ msgstr ""
|
|||
msgid "auth.confirm-password"
|
||||
msgstr "Bekreft passord"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs, src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
#, fuzzy
|
||||
msgid "auth.email"
|
||||
msgstr "E-post"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Glemt passordet?"
|
||||
|
|
|
@ -39,11 +39,6 @@ msgstr ""
|
|||
"Dit is een DEMO-service, GEBRUIK DIT NIET voor echt werk, de projecten "
|
||||
"worden regelmatig gewist."
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs,
|
||||
#: src/app/main/ui/auth/recovery_request.cljs, src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: src/app/main/ui/auth/login.cljs
|
||||
msgid "auth.forgot-password"
|
||||
msgstr "Wachtwoord vergeten?"
|
||||
|
@ -173,10 +168,6 @@ msgstr "Nog geen account?"
|
|||
msgid "auth.register-submit"
|
||||
msgstr "Account aanmaken"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-subtitle"
|
||||
msgstr "Het is gratis, het is open source"
|
||||
|
||||
#: src/app/main/ui/auth/register.cljs
|
||||
msgid "auth.register-title"
|
||||
msgstr "Account aanmaken"
|
||||
|
@ -2503,10 +2494,6 @@ msgstr "2-10"
|
|||
msgid "questions.31-50"
|
||||
msgstr "31-50"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.a-lot"
|
||||
msgstr "Veel"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.adobe-xd"
|
||||
msgstr "Adobe XD"
|
||||
|
@ -2515,62 +2502,22 @@ msgstr "Adobe XD"
|
|||
msgid "questions.canva"
|
||||
msgstr "Canva"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.describe-your-experience-working-on"
|
||||
msgstr "Hoe zou je je ervaring omschrijven voor het werken aan..."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.designer"
|
||||
msgstr "Ontwerper"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.developer"
|
||||
msgstr "Ontwikkelaar"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.discover-more-about-penpot"
|
||||
msgstr "Meer over Penpot ontdekken"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.figma"
|
||||
msgstr "Figma"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.founder"
|
||||
msgstr "Oprichter/VP"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.freelancer"
|
||||
msgstr "Ik ben een freelancer"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.get-the-code-from-my-team-project"
|
||||
msgstr "Haal de code op van mijn teamproject "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.interface-design-visual-assets-design-systems"
|
||||
msgstr "... interfaceontwerp, visuel assets, design systems, enz."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.invision"
|
||||
msgstr "InVision"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.leave-feedback-for-my-team-project"
|
||||
msgstr "Laat feedback achter voor mijn teamproject"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.lets-get-started"
|
||||
msgstr "Laten we beginnen!"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.manager"
|
||||
msgstr "Product- of projectmanager"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.marketing"
|
||||
msgstr "Marketing"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.more-than-50"
|
||||
msgstr "Meer dan 50"
|
||||
|
@ -2583,10 +2530,6 @@ msgstr "Geen"
|
|||
msgid "questions.next"
|
||||
msgstr "Volgende"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.none"
|
||||
msgstr "Geen"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.other"
|
||||
msgstr "Anders (namelijk…)"
|
||||
|
@ -2599,14 +2542,6 @@ msgstr "Ik werk aan een persoonlijk project"
|
|||
msgid "questions.previous"
|
||||
msgstr "Vorige"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.questions-how-are-you-planning-to-use-penpot"
|
||||
msgstr "Hoe ben je van plan Penpot te gebruiken?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.role"
|
||||
msgstr "Wat is je rol?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.select-option"
|
||||
msgstr "Selecteer een optie"
|
||||
|
@ -2615,50 +2550,14 @@ msgstr "Selecteer een optie"
|
|||
msgid "questions.sketch"
|
||||
msgstr "Sketch"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.some"
|
||||
msgstr "Sommige"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start"
|
||||
msgstr "Starten"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.start-to-work-on-my-project"
|
||||
msgstr "Begin aan mijn project te werken"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.student-teacher"
|
||||
msgstr "Student of docent"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.team-size"
|
||||
msgstr "Hoe groot is je team?"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.test-penpot-to-see-if-its-a-fit-for-team"
|
||||
msgstr "Penpot testen om te zien of het geschikt is voor het team "
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.try-out-before-using-penpot-on-premise"
|
||||
msgstr "Probeer uit voordat je Penpot on-premise gebruikt"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.wireframes-user-journeys-flows-navigation-trees"
|
||||
msgstr ""
|
||||
"… draadmodellen, gebruikers journeys en stroomdiagrammen, navigatiebomen, "
|
||||
"etc."
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.work-in-concept-ideas"
|
||||
msgstr "Werken in conceptideeën"
|
||||
|
||||
#: src/app/main/ui/onboarding/questions.cljs
|
||||
msgid "questions.your-feedback-will-help-us"
|
||||
msgstr ""
|
||||
"Jouw feedback helpt ons te begrijpen wat je gewoonten en voorkeuren zijn, "
|
||||
"zodat we van Penpot een nuttig en plezierig hulpmiddel kunnen blijven maken."
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs,
|
||||
msgid "settings.detach"
|
||||
msgstr "Ontkoppelen"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue