Compare commits

...

7 Commits

Author SHA1 Message Date
Andrey Antukh
b8c70be9a2 Make frontend build and watch process more resilent to errors 2026-01-21 13:44:35 +01:00
Andrey Antukh
525adcfcbe Add wasm build on watch app script (devenv) 2026-01-21 13:44:35 +01:00
Eva Marco
7cce4c6532 🐛 Fix unhandled exception tokens creation dialog (#8136) 2026-01-21 13:09:22 +01:00
Alejandro Alonso
a3fdd8b691 Merge pull request #8147 from penpot/niwinz-staging-file-menu-issue
 Use correct team-id on file-menu on dashboard
2026-01-21 12:54:28 +01:00
Andrey Antukh
b6a9579c98 Use correct team-id on file-menu on dashboard
Before the changes on this commit, the team object is used for
retrieve the id, where we already have team-id. Additionally, the
team object resolution is async operation and is not available on
the first render which causes strange issues on automated flows
(playwright) where an option is clicked when the async flow is
still pending and we have no team object loaded.
2026-01-21 12:23:44 +01:00
Eva Marco
8c7fd0af4b 🐛 Fix shadow reference validation (#8132) 2026-01-21 09:17:03 +01:00
Andrey Antukh
cf46051f56 🔥 Remove .traivis.yml file from the repository 2026-01-20 19:40:31 +01:00
16 changed files with 112 additions and 80 deletions

View File

@@ -1,40 +0,0 @@
dist: xenial
language: generic
sudo: required
cache:
directories:
- $HOME/.m2
services:
- docker
branches:
only:
- master
- develop
install:
- curl -O https://download.clojure.org/install/linux-install-1.10.1.447.sh
- chmod +x linux-install-1.10.1.447.sh
- sudo ./linux-install-1.10.1.447.sh
before_script:
- env | sort
script:
- ./manage.sh build-devenv
- ./manage.sh run-frontend-tests
- ./manage.sh run-backend-tests
- ./manage.sh build-images
- ./manage.sh run
after_script:
- docker images
notifications:
email: false
env:
- NODE_VERSION=10.16.0

View File

@@ -29,7 +29,7 @@
- Fix missing text color token from selected shapes in selected colors list [Taiga #12956](https://tree.taiga.io/project/penpot/issue/12956)
- Fix dropdown option width in Guides columns dropdown [Taiga #12959](https://tree.taiga.io/project/penpot/issue/12959)
- Fix typos on download modal [Taiga #12865](https://tree.taiga.io/project/penpot/issue/12865)
- Fix unhandled exception tokens creation dialog [Github #8110](https://github.com/penpot/penpot/issues/8110)
## 2.12.1

View File

@@ -48,7 +48,7 @@
"watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook",
"clear:shadow-cache": "rm -rf .shadow-cljs",
"watch": "exit 0",
"watch:app": "yarn run clear:shadow-cache && concurrently --kill-others-on-fail \"yarn run watch:app:assets\" \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
"watch:app": "yarn run clear:shadow-cache && yarn run build:wasm && concurrently --kill-others-on-fail \"yarn run watch:app:assets\" \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
"watch:storybook": "yarn run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\""
},
"devDependencies": {

View File

@@ -174,6 +174,7 @@ export async function watch(baseDir, predicate, callback) {
const watcher = new Watcher(baseDir, {
persistent: true,
recursive: true,
debounce: 500
});
watcher.on("change", (path) => {
@@ -181,8 +182,19 @@ export async function watch(baseDir, predicate, callback) {
callback(path);
}
});
watcher.on("error", (cause) => {
console.log("WATCHER ERROR", cause);
});
}
export async function ensureDirectories() {
await fs.mkdir("./resources/public/js/worker/", { recursive: true });
await fs.mkdir("./resources/public/css/", { recursive: true });
}
async function readManifestFile(resource) {
const manifestPath = "resources/public/" + resource;
let content = await fs.readFile(manifestPath, { encoding: "utf8" });
@@ -260,6 +272,9 @@ const markedOptions = {
marked.use(markedOptions);
export async function compileTranslations() {
const outputDir = "resources/public/js/";
await fs.mkdir(outputDir, { recursive: true });
const langs = [
"ar",
"ca",
@@ -341,7 +356,6 @@ export async function compileTranslations() {
}
const esm = `export default ${JSON.stringify(result, null, 0)};\n`;
const outputDir = "resources/public/js/";
const outputFile = ph.join(outputDir, "translation." + lang + ".js");
await fs.writeFile(outputFile, esm);
}
@@ -499,17 +513,43 @@ export async function compileStyles() {
export async function compileSvgSprites() {
const start = process.hrtime();
log.info("init: compile svgsprite");
await generateSvgSprites();
let error = false;
try {
await generateSvgSprites();
} catch (cause) {
error = cause;
}
const end = process.hrtime(start);
log.info("done: compile svgsprite", `(${ppt(end)})`);
if (error) {
log.error("error: compile svgsprite", `(${ppt(end)})`);
console.error(error);
} else {
log.info("done: compile svgsprite", `(${ppt(end)})`);
}
}
export async function compileTemplates() {
const start = process.hrtime();
let error = false;
log.info("init: compile templates");
await generateTemplates();
try {
await generateTemplates();
} catch (cause) {
error = cause;
}
const end = process.hrtime(start);
log.info("done: compile templates", `(${ppt(end)})`);
if (error) {
log.error("error: compile templates", `(${ppt(end)})`);
console.error(error);
} else {
log.info("done: compile templates", `(${ppt(end)})`);
}
}
export async function compilePolyfills() {

View File

@@ -28,14 +28,12 @@ async function compileFile(path) {
],
sourceMap: false,
});
// console.dir(result);
resolve({
inputPath: path,
outputPath: dest,
css: result.css,
});
} catch (cause) {
console.error(cause);
reject(cause);
}
});

View File

@@ -1,5 +1,6 @@
import * as h from "./_helpers.js";
await h.ensureDirectories();
await h.compileStyles();
await h.copyAssets();
await h.copyWasmPlayground();

View File

@@ -12,19 +12,31 @@ let sass = null;
async function compileSassAll() {
const start = process.hrtime();
let error = false;
log.info("init: compile styles");
sass = await h.compileSassAll(worker);
let output = await h.concatSass(sass);
await fs.writeFile("./resources/public/css/main.css", output);
try {
sass = await h.compileSassAll(worker);
let output = await h.concatSass(sass);
await fs.writeFile("./resources/public/css/main.css", output);
if (isDebug) {
let debugCSS = await h.compileSassDebug(worker);
await fs.writeFile("./resources/public/css/debug.css", debugCSS);
if (isDebug) {
let debugCSS = await h.compileSassDebug(worker);
await fs.writeFile("./resources/public/css/debug.css", debugCSS);
}
} catch (cause) {
error = cause;
}
const end = process.hrtime(start);
log.info("done: compile styles", `(${ppt(end)})`);
if (error) {
log.error("error: compile styles", `(${ppt(end)})`);
console.error(error);
} else {
log.info("done: compile styles", `(${ppt(end)})`);
}
}
async function compileSass(path) {
@@ -48,7 +60,7 @@ async function compileSass(path) {
}
}
await fs.mkdir("./resources/public/css/", { recursive: true });
await h.ensureDirectories();
await compileSassAll();
await h.copyAssets();
await h.copyWasmPlayground();

View File

@@ -480,6 +480,9 @@
(def workspace-token-sets-tree
(l/derived (d/nilf ctob/get-set-tree) tokens-lib))
(def workspace-all-tokens-map
(l/derived (d/nilf ctob/get-all-tokens) tokens-lib))
(def workspace-active-theme-paths
(l/derived (d/nilf ctob/get-active-theme-paths) tokens-lib))

View File

@@ -193,11 +193,11 @@
restore-fn
(fn [_]
(st/emit! (dd/restore-files-immediately
(with-meta {:team-id (:id current-team)
(with-meta {:team-id current-team-id
:ids (into #{} d/xf:map-id files)}
{:on-success #(st/emit! (ntf/success (tr "dashboard.restore-success-notification" (:name file)))
(dd/fetch-projects (:id current-team))
(dd/fetch-deleted-files (:id current-team)))
(dd/fetch-projects current-team-id)
(dd/fetch-deleted-files current-team-id))
:on-error #(st/emit! (ntf/error (tr "dashboard.errors.error-on-restore-file" (:name file))))}))))
on-restore-immediately
@@ -214,7 +214,7 @@
on-delete-immediately
(fn []
(let [accept-fn #(st/emit! (dd/delete-files-immediately
{:team-id (:id current-team)
{:team-id current-team-id
:ids (into #{} d/xf:map-id files)}))]
(st/emit!
(modal/show {:type :confirm
@@ -244,8 +244,7 @@
(for [project current-projects]
{:name (get-project-name project)
:id (get-project-id project)
:handler (on-move (:id current-team)
(:id project))})
:handler (on-move current-team-id (:id project))})
(when (seq other-teams)
[{:name (tr "dashboard.move-to-other-team")
:id "move-to-other-team"

View File

@@ -23,6 +23,7 @@
touched? (and (contains? (:data @form) input-name)
(get-in @form [:touched input-name]))
error (get-in @form [:errors input-name])
value (get-in @form [:data input-name] "")

View File

@@ -140,6 +140,9 @@
error
(get-in @form [:errors input-name])
extra-error
(get-in @form [:extra-errors input-name])
value
(get-in @form [:data input-name] "")
@@ -247,9 +250,14 @@
:hint-type (:type hint)})
props
(if (and error touched?)
(cond
(and error touched?)
(mf/spread-props props {:hint-type "error"
:hint-message (:message error)})
(and extra-error touched?)
(mf/spread-props props {:hint-type "error"
:hint-message (:message extra-error)})
:else
props)]
(mf/with-effect [resolve-stream tokens token input-name]

View File

@@ -236,12 +236,14 @@
(on-composite-input-change form field value false))
([form field value trim?]
(letfn [(clean-errors [errors]
(-> errors
(dissoc field)
(not-empty)))]
(some-> errors
(update :value #(when (map? %) (dissoc % field)))
(update :value #(when (seq %) %))
(not-empty)))]
(swap! form (fn [state]
(-> state
(assoc-in [:data :value field] (if trim? (str/trim value) value))
(assoc-in [:touched :value field] true)
(update :errors clean-errors)
(update :extra-errors clean-errors)))))))
@@ -257,6 +259,9 @@
value
(get-in @form [:data :value input-name] "")
touched?
(get-in @form [:touched :value input-name])
resolve-stream
(mf/with-memo [token]
(if-let [value (get-in token [:value input-name])]
@@ -284,7 +289,7 @@
:hint-message (:message hint)
:hint-type (:type hint)})
props
(if error
(if (and touched? error)
(mf/spread-props props {:hint-type "error"
:hint-message (:message error)})
props)

View File

@@ -23,20 +23,19 @@
(let [token-type
(or (:type token) token-type)
tokens-in-selected-set
(mf/deref refs/workspace-all-tokens-in-selected-set)
token-path
(mf/with-memo [token]
(cft/token-name->path (:name token)))
tokens-tree-in-selected-set
(mf/with-memo [token-path tokens-in-selected-set]
(-> (ctob/tokens-tree tokens-in-selected-set)
all-tokens (mf/deref refs/workspace-all-tokens-map)
all-tokens
(mf/with-memo [token-path all-tokens]
(-> (ctob/tokens-tree all-tokens)
(d/dissoc-in token-path)))
props
(mf/spread-props props {:token-type token-type
:tokens-tree-in-selected-set tokens-tree-in-selected-set
:all-token-tree all-tokens
:token token})
text-case-props (mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-case-value-enter")})
text-decoration-props (mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-decoration-value-enter")})

View File

@@ -14,6 +14,7 @@
[app.main.constants :refer [max-input-length]]
[app.main.data.modal :as modal]
[app.main.data.workspace.tokens.application :as dwta]
[app.main.data.workspace.tokens.errors :as wte]
[app.main.data.workspace.tokens.library-edit :as dwtl]
[app.main.data.workspace.tokens.propagation :as dwtp]
[app.main.refs :as refs]
@@ -85,7 +86,7 @@
action
is-create
selected-token-set-id
tokens-tree-in-selected-set
all-token-tree
token-type
make-schema
input-component
@@ -123,8 +124,8 @@
(assoc (:name token) token)))
schema
(mf/with-memo [tokens-tree-in-selected-set active-tab]
(make-schema tokens-tree-in-selected-set active-tab))
(mf/with-memo [all-token-tree active-tab]
(make-schema all-token-tree active-tab))
initial
(mf/with-memo [token]
@@ -207,7 +208,11 @@
:value (:value valid-token)
:description description}))
(dwtp/propagate-workspace-tokens)
(modal/hide))))))))]
(modal/hide)))))
(fn [{:keys [errors]}]
(let [error-messages (wte/humanize-errors errors)
error-message (first error-messages)]
(swap! form assoc-in [:extra-errors :value] {:message error-message}))))))]
[:> fc/form* {:class (stl/css :form-wrapper)
:form form

View File

@@ -291,6 +291,7 @@
[:color {:optional true} [:maybe :string]]
[:color-result {:optional true} ::sm/any]
[:inset {:optional true} [:maybe :boolean]]]]]
(if (= active-tab :reference)
[:reference {:optional false} ::sm/text]
[:reference {:optional true} [:maybe :string]])]]

View File

@@ -7757,7 +7757,7 @@ msgstr "Line height (multiplicador, px o %) o {alias}"
#: src/app/main/data/workspace/tokens/errors.cljs:57
msgid "workspace.tokens.missing-references"
msgstr "Referéncias de tokens no encontradas:"
msgstr "Referencias de tokens no encontradas: "
#: src/app/main/ui/workspace/tokens/management/token_pill.cljs:123
msgid "workspace.tokens.more-options"