@@ -55,7 +55,7 @@ export function SortableDataTable({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<SortableContext value={{ order, onOrderChange }}>
|
<SortableContext.Provider value={{ order, onOrderChange }}>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<DataTable {...props} />
|
<DataTable {...props} />
|
||||||
{hasNext && loadNext && (
|
{hasNext && loadNext && (
|
||||||
@@ -70,7 +70,7 @@ export function SortableDataTable({
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</SortableContext>
|
</SortableContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function VendorsCell(props: Props) {
|
|||||||
organizationId: props.organizationId,
|
organizationId: props.organizationId,
|
||||||
}}
|
}}
|
||||||
items={(data) =>
|
items={(data) =>
|
||||||
data.organization?.vendors?.edges.map((edge) => edge.node) ?? []
|
data.organization?.vendors?.edges?.map((edge) => edge.node) ?? []
|
||||||
}
|
}
|
||||||
itemRenderer={({ item, onRemove }) => (
|
itemRenderer={({ item, onRemove }) => (
|
||||||
<VendorBadge vendor={item} onRemove={onRemove} />
|
<VendorBadge vendor={item} onRemove={onRemove} />
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export function useStateWithSchema<T extends ZodTypeAny>(
|
|||||||
const [state, setState] = useState(initialValue);
|
const [state, setState] = useState(initialValue);
|
||||||
const [value, errors] = useMemo((): [z.infer<T>, Record<string, string>] => {
|
const [value, errors] = useMemo((): [z.infer<T>, Record<string, string>] => {
|
||||||
try {
|
try {
|
||||||
|
schema.parse(state);
|
||||||
return [schema.parse(state), {}];
|
return [schema.parse(state), {}];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof ZodError) {
|
if (error instanceof ZodError) {
|
||||||
@@ -26,7 +27,7 @@ export function useStateWithSchema<T extends ZodTypeAny>(
|
|||||||
}, [state, schema]);
|
}, [state, schema]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rawValue: value,
|
rawValue: state,
|
||||||
value,
|
value,
|
||||||
errors,
|
errors,
|
||||||
update: useCallback(
|
update: useCallback(
|
||||||
|
|||||||
@@ -233,7 +233,9 @@ export default function AssetsPage(props: Props) {
|
|||||||
<VendorsCell
|
<VendorsCell
|
||||||
name="vendorIds"
|
name="vendorIds"
|
||||||
organizationId={organizationId}
|
organizationId={organizationId}
|
||||||
defaultValue={item?.vendors.edges.map((edge) => edge.node) ?? []}
|
defaultValue={
|
||||||
|
item?.vendors?.edges?.map((edge) => edge.node) ?? []
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ export default defineConfig({
|
|||||||
target: "http://localhost:8080",
|
target: "http://localhost:8080",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
|
"/authz": {
|
||||||
|
target: "http://localhost:8080",
|
||||||
|
changeOrigin: true,
|
||||||
|
},
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://localhost:8080",
|
target: "http://localhost:8080",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
@@ -29,7 +33,9 @@ export default defineConfig({
|
|||||||
"/pages": fileURLToPath(new URL("./src/pages", import.meta.url)),
|
"/pages": fileURLToPath(new URL("./src/pages", import.meta.url)),
|
||||||
"/routes": fileURLToPath(new URL("./src/routes", import.meta.url)),
|
"/routes": fileURLToPath(new URL("./src/routes", import.meta.url)),
|
||||||
"/providers": fileURLToPath(new URL("./src/providers", import.meta.url)),
|
"/providers": fileURLToPath(new URL("./src/providers", import.meta.url)),
|
||||||
"/permissions": fileURLToPath(new URL("./src/permissions", import.meta.url)),
|
"/permissions": fileURLToPath(
|
||||||
|
new URL("./src/permissions", import.meta.url),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
10
cfg/dev.yaml
10
cfg/dev.yaml
@@ -16,7 +16,7 @@ probod:
|
|||||||
trust-center:
|
trust-center:
|
||||||
http-addr: ":8085"
|
http-addr: ":8085"
|
||||||
https-addr: ":8443"
|
https-addr: ":8443"
|
||||||
|
|
||||||
api:
|
api:
|
||||||
addr: "localhost:8080"
|
addr: "localhost:8080"
|
||||||
cors:
|
cors:
|
||||||
@@ -101,11 +101,3 @@ probod:
|
|||||||
- "incoming-webhook"
|
- "incoming-webhook"
|
||||||
settings:
|
settings:
|
||||||
signing-secret: "this-is-not-a-secret-for-slack-signing"
|
signing-secret: "this-is-not-a-secret-for-slack-signing"
|
||||||
|
|
||||||
custom-domains:
|
|
||||||
renewal-interval: 3600
|
|
||||||
provision-interval: 30
|
|
||||||
acme:
|
|
||||||
directory: "https://localhost:14000/dir"
|
|
||||||
email: "bryan@getprobo.com"
|
|
||||||
key-type: "EC256"
|
|
||||||
|
|||||||
@@ -57,11 +57,7 @@ export function focusSiblingElement(direction = 1) {
|
|||||||
).filter((el) => {
|
).filter((el) => {
|
||||||
// Filter out elements that are not visible or have display: none
|
// Filter out elements that are not visible or have display: none
|
||||||
const style = window.getComputedStyle(el);
|
const style = window.getComputedStyle(el);
|
||||||
return (
|
return style.display !== "none" && style.visibility !== "hidden";
|
||||||
style.display !== "none" &&
|
|
||||||
style.visibility !== "hidden" &&
|
|
||||||
el.offsetParent !== null
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentIndex = focusableElements.indexOf(current);
|
const currentIndex = focusableElements.indexOf(current);
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ export function RowButton({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
{...props}
|
{...props}
|
||||||
|
type="button"
|
||||||
className="py-2 bg-highlight hover:bg-highlight-hover active:bg-highlight-pressed cursor-pointer w-full flex gap-2 items-center justify-center text-sm text-txt-secondary"
|
className="py-2 bg-highlight hover:bg-highlight-hover active:bg-highlight-pressed cursor-pointer w-full flex gap-2 items-center justify-center text-sm text-txt-secondary"
|
||||||
style={{ gridColumnEnd: -1, gridColumnStart: 1 }}
|
style={{ gridColumnEnd: -1, gridColumnStart: 1 }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ export function EditableRow(props: Props) {
|
|||||||
[props.errors],
|
[props.errors],
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<EditableRowContext value={value}>
|
<EditableRowContext.Provider value={value}>
|
||||||
<Row>{props.children}</Row>
|
<Row>{props.children}</Row>
|
||||||
</EditableRowContext>
|
</EditableRowContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EditableCell, useEditableCellRef } from "./EditableCell.tsx";
|
import { EditableCell, useEditableCellRef } from "./EditableCell.tsx";
|
||||||
import { type KeyboardEventHandler, useRef, useState } from "react";
|
import { type KeyboardEventHandler, useEffect, useRef, useState } from "react";
|
||||||
import { useEditableRowContext } from "./EditableRow.tsx";
|
import { useEditableRowContext } from "./EditableRow.tsx";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -27,6 +27,11 @@ export function TextCell(props: Props) {
|
|||||||
setValue(inputValue);
|
setValue(inputValue);
|
||||||
onUpdate(props.name, inputValue);
|
onUpdate(props.name, inputValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Keep the value in sync with the props.defaultValue if defaultValue changes
|
||||||
|
useEffect(() => {
|
||||||
|
setValue(props.defaultValue);
|
||||||
|
}, [props.defaultValue]);
|
||||||
return (
|
return (
|
||||||
<EditableCell
|
<EditableCell
|
||||||
name={props.name}
|
name={props.name}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export function getKey<T>(item: T): string {
|
|||||||
item &&
|
item &&
|
||||||
typeof item === "object" &&
|
typeof item === "object" &&
|
||||||
"id" in item &&
|
"id" in item &&
|
||||||
typeof item.id === "string"
|
(typeof item.id === "string" || typeof item.id === "number")
|
||||||
) {
|
) {
|
||||||
return item.id.toString();
|
return item.id.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user