import("./settings/BuilderSettings.vue"),
@@ -270,34 +271,33 @@ onMounted(() => {
@import "./sharedStyles.css";
.BuilderApp {
- --builderBackgroundColor: #ffffff;
- --builderAccentColor: #5551ff;
- --builderSuccessColor: #3be19b;
- --builderErrorColor: #ff3d00;
- --builderHeaderBackgroundColor: #333333;
- --builderHeaderBackgroundHoleColor: #000000;
+ --builderBackgroundColor: var(--wdsColorWhite);
+ --builderAccentColor: var(--wdsColorBlue5);
+ --builderSuccessColor: var(--wdsColorGreen5);
+ --builderErrorColor: var(--wdsColorOrange5);
+ --builderHeaderBackgroundColor: var(--wdsColorGray6);
+ --builderHeaderBackgroundHoleColor: var(--wdsColorBlack);
--builderPrimaryTextColor: rgba(0, 0, 0, 0.9);
--builderSecondaryTextColor: rgba(0, 0, 0, 0.6);
--builderAreaSeparatorColor: rgba(0, 0, 0, 0.2);
- --builderSeparatorColor: #e4e7ed;
- --builderSubtleSeparatorColor: #f5f5f9;
- --builderIntenseSeparatorColor: #d2d4d7;
- --builderSelectedColor: #e4e9ff;
- --builderMatchingColor: #f8dccc;
- --builderIntenseSelectedColor: #0094d1;
+ --builderSeparatorColor: var(--wdsColorGray2);
+ --builderSubtleSeparatorColor: var(--wdsColorGray1);
+ --builderIntenseSeparatorColor: var(--wdsColorGray3);
+ --builderSelectedColor: var(--wdsColorBlue2);
+ --builderMatchingColor: var(--wdsColorOrange2);
+ --builderIntenseSelectedColor: var(--wdsColorBlue4);
--builderSubtleHighlightColor: rgba(0, 0, 0, 0.05);
- --builderSubtleHighlightColorSolid: #f2f2f2;
- --builderDisabledColor: rgb(180, 180, 180);
+ --builderSubtleHighlightColorSolid: var(--wdsColorGray1);
--builderSidebarWidth: 265px;
--builderSettingsWidth: 450px;
- --builderActionOngoingColor: #333333;
+ --builderActionOngoingColor: var(--wdsColorGray6);
--builderTopBarHeight: 48px;
--builderWarningTextColor: white;
- --builderWarningColor: #ff3d00;
+ --builderWarningColor: var(--wdsColorOrange5);
--builderPanelSwitcherHeight: 48px;
--builderPanelSwitcherExpandedHeight: calc(50% - 24px);
- --buttonColor: #5551ff;
+ --buttonColor: var(--wdsColorBlue5);
--buttonTextColor: white;
--accentColor: var(--builderAccentColor);
--primaryTextColor: var(--builderPrimaryTextColor);
diff --git a/src/ui/src/builder/BuilderEmbeddedCodeEditor.vue b/src/ui/src/builder/BuilderEmbeddedCodeEditor.vue
index 4a2e3c923..7c348f1ac 100644
--- a/src/ui/src/builder/BuilderEmbeddedCodeEditor.vue
+++ b/src/ui/src/builder/BuilderEmbeddedCodeEditor.vue
@@ -59,6 +59,7 @@ onMounted(() => {
editor = monaco.editor.create(editorContainerEl.value, {
value: modelValue.value,
language: props.language,
+ readOnly: props.disabled,
...VARIANTS_SETTINGS[props.variant],
});
editor.getModel().onDidChangeContent(() => {
@@ -84,11 +85,11 @@ onUnmounted(() => {
.BuilderEmbeddedCodeEditor {
height: 100%;
width: 100%;
- min-height: 200px;
+ min-height: 100px;
}
.editorContainer {
- min-height: 200px;
+ min-height: 100px;
width: 100%;
height: 100%;
overflow: hidden;
diff --git a/src/ui/src/builder/BuilderHeader.vue b/src/ui/src/builder/BuilderHeader.vue
index 9fd17f11c..67e08d202 100644
--- a/src/ui/src/builder/BuilderHeader.vue
+++ b/src/ui/src/builder/BuilderHeader.vue
@@ -142,7 +142,7 @@ const customHandlerModalCloseAction: ModalAction = {
.panelToggler:hover {
font-size: 12px;
--buttonColor: black;
- --builderSeparatorColor: #303030;
+ --builderSeparatorColor: var(--wdsColorGray6);
--buttonTextColor: white;
}
diff --git a/src/ui/src/builder/BuilderModal.vue b/src/ui/src/builder/BuilderModal.vue
index 62cbf4a4d..12ab381a7 100644
--- a/src/ui/src/builder/BuilderModal.vue
+++ b/src/ui/src/builder/BuilderModal.vue
@@ -1,7 +1,12 @@
-
+
{{
@@ -38,19 +43,24 @@
+
+
diff --git a/src/ui/src/builder/settings/BuilderSettings.vue b/src/ui/src/builder/settings/BuilderSettings.vue
index 06edb8b10..9a1750112 100644
--- a/src/ui/src/builder/settings/BuilderSettings.vue
+++ b/src/ui/src/builder/settings/BuilderSettings.vue
@@ -114,7 +114,7 @@ const toggleMiniDocs = () => {
overflow: hidden;
border-width: 1px solid var(--builderAreaSeparatorColor);
background: var(--builderBackgroundColor);
- box-shadow: 0px 3px 40px 0px rgba(172, 185, 220, 0.4);
+ box-shadow: var(--wdsShadowLarge);
border-radius: 12px;
top: v-bind("ssbm.getMode() == `workflows` ? `72px` : `20px`");
}
diff --git a/src/ui/src/builder/settings/BuilderSettingsAPICode.vue b/src/ui/src/builder/settings/BuilderSettingsAPICode.vue
new file mode 100644
index 000000000..9586c4b1d
--- /dev/null
+++ b/src/ui/src/builder/settings/BuilderSettingsAPICode.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+ The following call will create the job and provide you with
+ a job ID and a job token.
+
+
+
+ Using the job ID and token obtained in the previous call,
+ check the status of the job. You can use the code below,
+ after replacing JOB_ID and JOB_TOKEN for the right values.
+
+
+
+ Note: For API calls to work, the --enable-jobs-api flag
+ must be active.
+
+
+ API code cannot be generated. Please make sure the
+ environment variable WRITER_SECRET_KEY has been set up.
+
+
+
+
+
+ code Call via
+ API
+
+
+
+ code Call via
+ API
+
+
+
+
+
+
+
diff --git a/src/ui/src/builder/settings/BuilderSettingsBinding.vue b/src/ui/src/builder/settings/BuilderSettingsBinding.vue
index b6ffcc419..b025f7742 100644
--- a/src/ui/src/builder/settings/BuilderSettingsBinding.vue
+++ b/src/ui/src/builder/settings/BuilderSettingsBinding.vue
@@ -1,15 +1,10 @@
-
- link
-
Binding
-
+
-
-
State element
+
-
- Links this component to a state element, in a two-way
- fashion. Reference the state element directly, i.e. use
- "my_var" instead of "@{my_var}".
-
-
+
@@ -35,6 +25,10 @@ import { computed, inject } from "vue";
import { useComponentActions } from "../useComponentActions";
import injectionKeys from "../../injectionKeys";
import BuilderTemplateInput from "./BuilderTemplateInput.vue";
+import WdsFieldWrapper from "@/wds/WdsFieldWrapper.vue";
+
+const hint =
+ 'Links this component to a state element, in a two-way fashion. Reference the state element directly, i.e. use "my_var" instead of "@{my_var}".';
const wf = inject(injectionKeys.core);
const ssbm = inject(injectionKeys.builderManager);
diff --git a/src/ui/src/builder/settings/BuilderSettingsHandlers.vue b/src/ui/src/builder/settings/BuilderSettingsHandlers.vue
index 96d74fc6f..d93c3d43e 100644
--- a/src/ui/src/builder/settings/BuilderSettingsHandlers.vue
+++ b/src/ui/src/builder/settings/BuilderSettingsHandlers.vue
@@ -1,47 +1,39 @@
-
+
bolt
Events
-
+
-
-
{{ eventType }}
-
-
-
-
-
-
- help
-
-
-
-
- {{ eventInfo.desc }}
+
+
+
+
+ add Add custom handler
+
-
- content_copy
+
+ content_copy
Copy code to clipboard
-
+
-
-
- add Add custom handler
-
-
-
-
- add Add
-
-
-
+
+ add Add
+
+
@@ -150,6 +112,9 @@ import BuilderModal, { ModalAction } from "../BuilderModal.vue";
import { WriterComponentDefinition } from "@/writerTypes";
import BuilderSelect from "../BuilderSelect.vue";
import type { Option } from "../BuilderSelect.vue";
+import WdsFieldWrapper from "@/wds/WdsFieldWrapper.vue";
+import WdsTextInput from "@/wds/WdsTextInput.vue";
+import WdsButton from "@/wds/WdsButton.vue";
const wf = inject(injectionKeys.core);
const ssbm = inject(injectionKeys.builderManager);
@@ -182,7 +147,7 @@ const options = computed
(() => {
];
});
-function getOptions(eventType: string): Option[] {
+function getOptions(eventType?: string): Option[] {
if (!isHandlerInvalid(eventType)) return options.value;
const handler = component.value.handlers?.[eventType];
@@ -359,38 +324,22 @@ const copyToClipboard = (text: string) => {
diff --git a/src/ui/src/builder/settings/BuilderSettingsMain.vue b/src/ui/src/builder/settings/BuilderSettingsMain.vue
index 68ddd2564..fd98b7f47 100644
--- a/src/ui/src/builder/settings/BuilderSettingsMain.vue
+++ b/src/ui/src/builder/settings/BuilderSettingsMain.vue
@@ -22,6 +22,7 @@
+ Execute via API
@@ -42,6 +43,7 @@ import BuilderSettingsBinding from "./BuilderSettingsBinding.vue";
import BuilderSettingsVisibility from "./BuilderSettingsVisibility.vue";
import BuilderCopyText from "../BuilderCopyText.vue";
import BuilderAsyncLoader from "../BuilderAsyncLoader.vue";
+import BuilderSettingsAPICode from "./BuilderSettingsAPICode.vue";
const BuilderSettingsHandlers = defineAsyncComponent({
loader: () => import("./BuilderSettingsHandlers.vue"),
diff --git a/src/ui/src/builder/settings/BuilderSettingsProperties.vue b/src/ui/src/builder/settings/BuilderSettingsProperties.vue
index 950184fda..b760fac0a 100644
--- a/src/ui/src/builder/settings/BuilderSettingsProperties.vue
+++ b/src/ui/src/builder/settings/BuilderSettingsProperties.vue
@@ -4,44 +4,46 @@
class="BuilderSettingsProperties"
>
-
-
{{ propertyCategory }}
-
+
+ {{ propertyCategory }}
+
-
-
- {{ fieldValue.name ?? fieldKey
- }} : {{ fieldValue.type }}
-
-
+
@@ -108,11 +105,7 @@
:component-id="selectedComponent.id"
>
-
-
- {{ fieldValue.desc }}
-
-
+
@@ -132,6 +125,7 @@ import BuilderFieldsShadow from "./BuilderFieldsShadow.vue";
import BuilderFieldsText from "./BuilderFieldsText.vue";
import BuilderFieldsWidth from "./BuilderFieldsWidth.vue";
import BuilderFieldsTools from "./BuilderFieldsTools.vue";
+import WdsFieldWrapper from "@/wds/WdsFieldWrapper.vue";
const wf = inject(injectionKeys.core);
const ssbm = inject(injectionKeys.builderManager);
@@ -150,11 +144,13 @@ const fields = computed(() => {
return definition.fields;
});
-const fieldCategories = [
- FieldCategory.General,
- FieldCategory.Style,
- FieldCategory.Tools,
-];
+const fieldCategories = computed(() => {
+ return [
+ FieldCategory.General,
+ FieldCategory.Style,
+ FieldCategory.Tools,
+ ].filter((c) => fieldsByCategory.value[c]?.length);
+});
const fieldsByCategory = computed(() => {
const entries = Object.entries(fields.value);
@@ -179,17 +175,22 @@ const fieldsByCategory = computed(() => {
@import "../sharedStyles.css";
.BuilderSettingsProperties {
+ padding: 24px;
+
display: flex;
flex-direction: column;
- gap: 24px;
+ gap: 16px;
}
-textarea.content {
- resize: vertical;
- height: 8em;
+.BuilderSettingsProperties__category {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
}
-input[type="color"].content {
- height: 48px;
+.BuilderSettingsProperties__category__title {
+ color: var(--builderSecondaryTextColor);
+ font-weight: 500;
+ font-size: 12px;
}
diff --git a/src/ui/src/builder/settings/BuilderSettingsVisibility.vue b/src/ui/src/builder/settings/BuilderSettingsVisibility.vue
index 9e2f7358f..5eb6fcd32 100644
--- a/src/ui/src/builder/settings/BuilderSettingsVisibility.vue
+++ b/src/ui/src/builder/settings/BuilderSettingsVisibility.vue
@@ -1,59 +1,18 @@
-
- visibility
-
Visibility
-
+
-
-
setVisibleValue(component.id, true)"
- >
- Yes
-
-
setVisibleValue(component.id, false)"
- >
- No
-
-
- setVisibleValue(
- component.id,
- 'custom',
- component.visible?.binding,
- component.visible?.reversed,
- )
- "
- >
- Custom
-
-
-
+
- Visibility value
@@ -80,12 +39,7 @@
"
/>Reverse
-
- Reference a state or context element that will evaluate to
- true or false. Reference the element directly, i.e. use
- "my_var" instead of "@{my_var}".
-
-
+
@@ -95,12 +49,49 @@ import { computed, inject } from "vue";
import { useComponentActions } from "../useComponentActions";
import injectionKeys from "../../injectionKeys";
import BuilderTemplateInput from "./BuilderTemplateInput.vue";
+import WdsFieldWrapper from "@/wds/WdsFieldWrapper.vue";
+import BuilderSectionTitle from "./BuilderSectionTitle.vue";
+import WdsTabs, { WdsTabOptions } from "@/wds/WdsTabs.vue";
+
+type Mode = "yes" | "no" | "custom";
+
+const tabs: WdsTabOptions
[] = [
+ { label: "Yes", value: "yes" },
+ { label: "No", value: "no" },
+ { label: "Custom", value: "custom" },
+];
+
+const tab = computed({
+ get() {
+ const visible = component.value.visible;
+ if (visible?.expression === "custom") return "custom";
+
+ return visible === undefined || visible.expression === true
+ ? "yes"
+ : "no";
+ },
+ set(value: Mode) {
+ if (value === "custom") {
+ setVisibleValue(
+ component.value.id,
+ "custom",
+ component.value.visible?.binding,
+ component.value.visible?.reversed,
+ );
+ } else {
+ setVisibleValue(component.value.id, value === "yes");
+ }
+ },
+});
const wf = inject(injectionKeys.core);
const ssbm = inject(injectionKeys.builderManager);
const { setVisibleValue } = useComponentActions(wf, ssbm);
const component = computed(() => wf.getComponentById(ssbm.getSelectedId()));
+
+const hint =
+ 'Reference a state or context element that will evaluate to true or false. Reference the element directly, i.e. use "my_var" instead of "@{my_var}".';
diff --git a/src/ui/src/components/workflows/base/WorkflowMiniMap.vue b/src/ui/src/components/workflows/base/WorkflowMiniMap.vue
index 2311835a9..5a11d3b9d 100644
--- a/src/ui/src/components/workflows/base/WorkflowMiniMap.vue
+++ b/src/ui/src/components/workflows/base/WorkflowMiniMap.vue
@@ -232,7 +232,7 @@ onUnmounted(() => {
}
.node.selected {
- background: #6985ff;
+ background: var(--wdsColorBlue4);
}
.selectedArea {
@@ -248,7 +248,7 @@ onUnmounted(() => {
position: absolute;
top: 0px;
left: 0px;
- border: 1px solid #6985ff;
+ border: 1px solid var(--wdsColorBlue4);
border-radius: 4px;
pointer-events: none;
display: v-bind("selector.isDisplayed ? '' : 'none'");
diff --git a/src/ui/src/core/index.ts b/src/ui/src/core/index.ts
index 8368d99ea..7a1e33f70 100644
--- a/src/ui/src/core/index.ts
+++ b/src/ui/src/core/index.ts
@@ -333,6 +333,35 @@ export function generateCore() {
sendFrontendMessage("event", messagePayload, callback, true);
}
+ /**
+ * Sends a message to be hashed in the backend using the relevant keys.
+ * Due to security reasons, it works only in edit mode.
+ *
+ * @param message Messaged to be hashed
+ * @returns The hashed message
+ */
+ async function hashMessage(message: string):Promise {
+ return new Promise((resolve, reject) => {
+ const messageCallback = (r: {
+ ok: boolean;
+ payload?: Record;
+ }) => {
+ if (!r.ok) {
+ reject("Couldn't connect to the server.");
+ return;
+ }
+ resolve(r.payload?.message);
+ };
+
+ sendFrontendMessage(
+ "hashRequest",
+ { message },
+ messageCallback,
+ );
+ });
+
+ }
+
async function sendCodeSaveRequest(newCode: string): Promise {
const messageData = {
code: newCode,
@@ -572,6 +601,7 @@ export function generateCore() {
addMailSubscription,
init,
forwardEvent,
+ hashMessage,
runCode: readonly(runCode),
sendCodeSaveRequest,
sendCodeUpdate,
diff --git a/src/ui/src/renderer/ComponentRenderer.vue b/src/ui/src/renderer/ComponentRenderer.vue
index 7bc2b0e8a..0feb6cd02 100644
--- a/src/ui/src/renderer/ComponentRenderer.vue
+++ b/src/ui/src/renderer/ComponentRenderer.vue
@@ -41,6 +41,7 @@ import {
changeRouteVarsInHash,
serializeParsedHash,
} from "@/core/navigation";
+import { WDS_CSS_PROPERTIES } from "@/wds/tokens";
const wf = inject(injectionKeys.core);
const wfbm = inject(injectionKeys.builderManager);
@@ -59,6 +60,7 @@ const coreRootFields = templateEvaluator.getEvaluatedFields([
const rootStyle = computed(() => {
return {
+ ...WDS_CSS_PROPERTIES,
"--accentColor": coreRootFields.accentColor?.value,
"--emptinessColor": coreRootFields.emptinessColor?.value,
"--containerBackgroundColor":
@@ -239,14 +241,14 @@ onMounted(() => {
@import "./sharedStyles.css";
.ComponentRenderer {
- --accentColor: #5551ff;
- --buttonColor: #5551ff;
- --emptinessColor: #ffffff;
- --separatorColor: #e4e7ed;
- --primaryTextColor: #000000;
- --buttonTextColor: #ffffff;
- --secondaryTextColor: #828282;
- --containerBackgroundColor: #ffffff;
+ --accentColor: var(--wdsColorBlue5);
+ --buttonColor: var(--wdsColorBlue5);
+ --emptinessColor: var(--wdsColorWhite);
+ --separatorColor: var(--wdsColorGray2);
+ --primaryTextColor: var(--wdsColorBlack);
+ --buttonTextColor: var(--wdsColorWhite);
+ --secondaryTextColor: var(--wdsColorGray4);
+ --containerBackgroundColor: var(--wdsColorWhite);
--containerShadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.05);
width: 100%;
outline: none;
diff --git a/src/ui/src/renderer/RendererNotifications.vue b/src/ui/src/renderer/RendererNotifications.vue
index 084d104bd..82fe2d1a1 100644
--- a/src/ui/src/renderer/RendererNotifications.vue
+++ b/src/ui/src/renderer/RendererNotifications.vue
@@ -103,7 +103,7 @@ const clearAll = () => {
max-width: 70ch;
width: 40vw;
z-index: 3;
- --buttonColor: #5551ff;
+ --buttonColor: var(--wdsColorBlue5);
}
.balloonFlash {
diff --git a/src/ui/src/wds/WdsButton.vue b/src/ui/src/wds/WdsButton.vue
index c665c24d7..c75d20aea 100644
--- a/src/ui/src/wds/WdsButton.vue
+++ b/src/ui/src/wds/WdsButton.vue
@@ -66,62 +66,62 @@ const className = computed(() => [
background: var(--intensifiedButtonColor);
}
.WdsButton--primary:disabled {
- border-color: #4a46da;
- background-color: #4a46da;
+ border-color: var(--wdsColorBlue6);
+ background-color: var(--wdsColorBlue6);
}
/* VARIANTS -- secondary */
.WdsButton--secondary {
color: var(--buttonTextColor);
- background: #000000;
- border-color: #000000;
+ background: var(--wdsColorBlack);
+ border-color: var(--wdsColorBlack);
}
.WdsButton--secondary:hover,
.WdsButton--secondary:focus {
- border-color: #333333;
- background: #333333;
+ border-color: var(--wdsColorGray6);
+ background: var(--wdsColorGray6);
}
.WdsButton--secondary:disabled {
- border-color: #333333;
- background: #333333;
+ border-color: var(--wdsColorGray6);
+ background: var(--wdsColorGray6);
opacity: 40%;
}
/* VARIANTS -- tertiary */
.WdsButton--tertiary {
- color: #000000;
- background: #ffffff;
- border-color: #e4e7ed;
+ color: var(--wdsColorBlack);
+ background: var(--wdsColorWhite);
+ border-color: var(--wdsColorGray2);
}
.WdsButton--tertiary:hover,
.WdsButton--tertiary:focus {
- color: #828282;
+ color: var(--wdsColorGray4);
}
.WdsButton--tertiary:disabled {
- color: #828282;
+ color: var(--wdsColorGray4);
opacity: 50%;
}
/* VARIANTS -- special */
.WdsButton--special {
- color: #5551ff;
- background: #e4e9ff;
- border-color: #e4e9ff;
+ color: var(--wdsColorBlue5);
+ background: var(--wdsColorBlue2);
+ border-color: var(--wdsColorBlue2);
}
.WdsButton--special:hover,
.WdsButton--special:focus {
- border-color: #bfcbff;
- background: #bfcbff;
+ border-color: var(--wdsColorBlue3);
+ background: var(--wdsColorBlue3);
}
.WdsButton--special:disabled {
- border-color: #e4e9ff;
- background-color: #e4e9ff;
+ border-color: var(--wdsColorBlue2);
+ background-color: var(--wdsColorBlue2);
opacity: 0.4;
}
diff --git a/src/ui/src/wds/WdsDropdownMenu.vue b/src/ui/src/wds/WdsDropdownMenu.vue
index 04d893e70..6633d8b70 100644
--- a/src/ui/src/wds/WdsDropdownMenu.vue
+++ b/src/ui/src/wds/WdsDropdownMenu.vue
@@ -1,15 +1,17 @@