mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-19 19:21:15 -05:00
Merge branch 'main' into fix/product-settings-form
This commit is contained in:
@@ -8,7 +8,7 @@ export const metadata = {
|
||||
|
||||
# Advanced Setup
|
||||
|
||||
Quickly set up and start using Formbricks with our [official Docker image](https://github.com/formbricks/formbricks/pkgs/container/formbricks) that we've already built for you.
|
||||
Quickly set up and start using Formbricks with our [official Docker image](https://github.com/formbricks/formbricks/pkgs/container/formbricks) that we've already built for you.
|
||||
|
||||
The pre-built image is ready-to-run, and it only requires minimal configuration on your part. It's as easy as downloading the Docker image and firing up the container.
|
||||
|
||||
@@ -104,20 +104,12 @@ You're now ready to start the Formbricks Docker setup. The following command wil
|
||||
|
||||
## Update
|
||||
|
||||
1. Stop the Formbricks stack
|
||||
<Note>
|
||||
Please take a look at our [migration guide](/self-hosting/migration-guide) for version specific steps to
|
||||
update Formbricks.
|
||||
</Note>
|
||||
|
||||
<Col>
|
||||
<CodeGroup title="Stop the docker instance">
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
</Col>
|
||||
|
||||
2. Pull the latest changes
|
||||
1. Pull the latest Formbricks image
|
||||
|
||||
<Col>
|
||||
<CodeGroup title="Pull the changes into docker">
|
||||
@@ -130,8 +122,20 @@ You're now ready to start the Formbricks Docker setup. The following command wil
|
||||
|
||||
</Col>
|
||||
|
||||
3. Update env vars as necessary in the docker-compose file.
|
||||
4. Re-start the Formbricks stack
|
||||
2. Stop the Formbricks stack
|
||||
|
||||
<Col>
|
||||
<CodeGroup title="Stop the docker instance">
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
</Col>
|
||||
|
||||
3. Re-start the Formbricks stack with the updated image
|
||||
|
||||
<Col>
|
||||
<CodeGroup title="Relaunch the Docker Instance">
|
||||
|
||||
@@ -24,6 +24,13 @@ export const POST = async (req: Request, context: Context): Promise<Response> =>
|
||||
const { userId, environmentId } = context.params;
|
||||
const jsonInput = await req.json();
|
||||
|
||||
// transform all attributes to string if attributes are present
|
||||
if (jsonInput.attributes) {
|
||||
for (const key in jsonInput.attributes) {
|
||||
jsonInput.attributes[key] = String(jsonInput.attributes[key]);
|
||||
}
|
||||
}
|
||||
|
||||
// validate using zod
|
||||
const inputValidation = z.object({ attributes: ZAttributes }).safeParse(jsonInput);
|
||||
|
||||
|
||||
@@ -16,11 +16,17 @@ export class AttributeAPI {
|
||||
async update(
|
||||
attributeUpdateInput: Omit<TAttributeUpdateInput, "environmentId">
|
||||
): Promise<Result<{ changed: boolean; message: string }, NetworkError | Error>> {
|
||||
// transform all attributes to string if attributes are present into a new attributes copy
|
||||
const attributes: { [key: string]: string } = {};
|
||||
for (const key in attributeUpdateInput.attributes) {
|
||||
attributes[key] = String(attributeUpdateInput.attributes[key]);
|
||||
}
|
||||
|
||||
return makeRequest(
|
||||
this.apiHost,
|
||||
`/api/v1/client/${this.environmentId}/people/${attributeUpdateInput.userId}/attributes`,
|
||||
"PUT",
|
||||
{ attributes: attributeUpdateInput.attributes }
|
||||
{ attributes }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@ import { AppConfig } from "./config";
|
||||
const appConfig = AppConfig.getInstance();
|
||||
const logger = Logger.getInstance();
|
||||
|
||||
export const updateAttribute = async (key: string, value: string): Promise<Result<void, NetworkError>> => {
|
||||
export const updateAttribute = async (
|
||||
key: string,
|
||||
value: string | number
|
||||
): Promise<Result<void, NetworkError>> => {
|
||||
const { apiHost, environmentId, userId } = appConfig.get();
|
||||
|
||||
const api = new FormbricksAPI({
|
||||
@@ -121,7 +124,7 @@ export const setAttributeInApp = async (
|
||||
return okVoid();
|
||||
}
|
||||
|
||||
const result = await updateAttribute(key, value.toString());
|
||||
const result = await updateAttribute(key, value);
|
||||
|
||||
if (result.ok) {
|
||||
// udpdate attribute in config
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
|
||||
interface ScrollableContainerProps {
|
||||
@@ -58,10 +59,8 @@ export const ScrollableContainer = ({ children }: ScrollableContainerProps) => {
|
||||
scrollbarGutter: "stable both-edges",
|
||||
maxHeight: isSurveyPreview ? "40dvh" : "60dvh",
|
||||
}}
|
||||
className={`overflow-${isOverflowHidden ? "hidden" : "auto"} px-4 pb-1`}
|
||||
className={cn("overflow-auto px-4 pb-1", isOverflowHidden ? "no-scrollbar" : "bg-survey-bg")}
|
||||
onMouseEnter={() => toggleOverflow(false)}
|
||||
onTouchStart={() => toggleOverflow(false)}
|
||||
onTouchEnd={() => toggleOverflow(true)}
|
||||
onMouseLeave={() => toggleOverflow(true)}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -130,6 +130,7 @@ export const StackedCardsContainer = ({
|
||||
<div style={{ height: cardHeight }}></div>
|
||||
{cardArrangement === "simple" ? (
|
||||
<div
|
||||
className="w-full"
|
||||
style={{
|
||||
...borderStyles,
|
||||
}}>
|
||||
|
||||
@@ -104,3 +104,18 @@ p.fb-editor-paragraph {
|
||||
width: 0%;
|
||||
}
|
||||
}
|
||||
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none !important; /* Internet Explorer 10+ */
|
||||
scrollbar-width: thin !important; /* Firefox */
|
||||
scrollbar-color: transparent transparent !important; /* Firefox */
|
||||
|
||||
/* Chrome, Edge, and Safari */
|
||||
&::-webkit-scrollbar {
|
||||
width: 0 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { z } from "zod";
|
||||
export const ZAttributeUpdateInput = z.object({
|
||||
environmentId: z.string().cuid2(),
|
||||
userId: z.string(),
|
||||
attributes: z.record(z.string()),
|
||||
attributes: z.record(z.union([z.string(), z.number()])),
|
||||
});
|
||||
|
||||
export type TAttributeUpdateInput = z.infer<typeof ZAttributeUpdateInput>;
|
||||
|
||||
@@ -128,8 +128,8 @@ export const SurveyCard = ({
|
||||
key={survey.id}
|
||||
className="relative grid w-full grid-cols-8 place-items-center gap-3 rounded-xl border border-slate-200 bg-white p-4
|
||||
shadow-sm transition-all ease-in-out hover:scale-[101%]">
|
||||
<div className="col-span-2 flex max-w-full items-center justify-self-start truncate whitespace-nowrap text-sm font-medium text-slate-900">
|
||||
{survey.name}
|
||||
<div className="col-span-2 flex max-w-full items-center justify-self-start text-sm font-medium text-slate-900">
|
||||
<div className="w-full truncate">{survey.name}</div>
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
Reference in New Issue
Block a user