-
Notifications
You must be signed in to change notification settings - Fork 936
feat: implement CRUD UI for IDP organization sync settings #15503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
d0baa8c
6463076
f714986
072d775
f6e286c
acf8cbe
ad1aa84
b01588d
6203d04
bc37998
2c2246d
6971f91
6e87130
a1b6e79
36c8706
a4e66c2
f7be49f
90a65fe
c282765
40155bc
a129820
8edd4b4
e54e5ca
bb16bd1
678a91d
a13d9b2
1b8efd1
137c25c
46a4646
85a455c
a9e06f1
d921b08
ba665b4
8a0e789
234c0fb
7d88a38
c6c9b16
5322a4e
eab8a0d
721d5d4
8986cbd
89a7b12
148dca7
0c338b0
0cadc8b
1d7153b
a914c54
bd307c0
95bfd17
82bd850
6eb6987
3822b2e
fe17b1c
e75e179
c6e07ff
a3b9b27
0601164
b01e5d3
1c5b6ef
6e2ee08
ae30db0
ac74cdc
a99dca5
4c00959
568a5a9
c313439
506223d
f223ab7
94ff4ca
9101e0e
5ca2c0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,5 +16,6 @@ | |
"ui": "/components/ui", | ||
"lib": "/lib", | ||
"hooks": "/hooks" | ||
} | ||
}, | ||
"iconLibrary": "lucide" | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { API } from "api/api"; | ||
import type { OrganizationSyncSettings } from "api/typesGenerated"; | ||
import type { QueryClient } from "react-query"; | ||
|
||
export const getOrganizationIdpSyncSettingsKey = () => [ | ||
"organizationIdpSyncSettings", | ||
]; | ||
|
||
export const patchOrganizationSyncSettings = (queryClient: QueryClient) => { | ||
return { | ||
mutationFn: (request: OrganizationSyncSettings) => | ||
API.patchOrganizationIdpSyncSettings(request), | ||
onSuccess: async () => | ||
await queryClient.invalidateQueries(getOrganizationIdpSyncSettingsKey()), | ||
}; | ||
}; | ||
|
||
export const organizationIdpSyncSettings = () => { | ||
return { | ||
queryKey: getOrganizationIdpSyncSettingsKey(), | ||
queryFn: () => API.getOrganizationIdpSyncSettings(), | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { type VariantProps, cva } from "class-variance-authority"; | ||
import type * as React from "react"; | ||
|
||
import { cn } from "utils/cn"; | ||
|
||
const badgeVariants = cva( | ||
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", | ||
{ | ||
variants: { | ||
variant: { | ||
default: | ||
"border-transparent bg-surface-secondary text-content-secondary shadow hover:bg-surface-tertiary", | ||
secondary: | ||
"border-transparent bg-surface-secondary text-content-secondary hover:bg-surface-tertiary", | ||
destructive: | ||
"border-transparent bg-surface-error text-content-danger shadow hover:bg-surface-error/80", | ||
outline: "text-content-primary", | ||
}, | ||
}, | ||
defaultVariants: { | ||
variant: "default", | ||
}, | ||
}, | ||
); | ||
|
||
export interface BadgeProps | ||
extends React.HTMLAttributes<HTMLDivElement>, | ||
VariantProps<typeof badgeVariants> {} | ||
|
||
function Badge({ className, variant, ...props }: BadgeProps) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: one thing we've been doing recently is bringing in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I think we should still use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, seems like a good idea. This means I should probably create a doc to list all the extra steps needed when importing a shadcn component. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @aslilac it would be useful to know the various reasons that components are currently written as they are. |
||
return ( | ||
<div className={cn(badgeVariants({ variant }), className)} {...props} /> | ||
); | ||
} | ||
|
||
export { Badge, badgeVariants }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what we've been doing in core lately, so just making sure I understand: are we going to be exporting styles like this going forward? At first blush, it's not super clear to me if this will serve a benefit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is definitely another shadcn-ism we should avoid. just put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My original thought was to keep the shadcn components as close as possible to how they are imported but it makes sense to change this since the current codebase convention is not to group all exports at the bottom of the file. I think this pattern is generally used so its easy to look up all exports in one place. @Parkreiner Since I have seen the export at the bottom pattern more often in other codebases, I am curious if you know why the current pattern exists? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, I haven't been in enough "big" codebases to notice any "industry-leading" patterns, but Coder was just like this when I started working for them. Though I am a bigger fan of just exporting any relevant values directly I know that |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On a similar note to the one about the style exports, are we changing how we're writing out code now? I few things immediately jump out to me:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Everything in |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import type { DialogProps } from "@radix-ui/react-dialog"; | ||
import { Command as CommandPrimitive } from "cmdk"; | ||
import { Search } from "lucide-react"; | ||
import * as React from "react"; | ||
|
||
import { Dialog, DialogContent } from "components/ui/dialog"; | ||
import { cn } from "utils/cn"; | ||
|
||
const Command = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive> | ||
>(({ className, ...props }, ref) => ( | ||
<CommandPrimitive | ||
ref={ref} | ||
className={cn( | ||
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-content-primary", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
)); | ||
Command.displayName = CommandPrimitive.displayName; | ||
jaaydenh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const CommandDialog = ({ children, ...props }: DialogProps) => { | ||
return ( | ||
<Dialog {...props}> | ||
<DialogContent className="overflow-hidden p-0"> | ||
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like I'm missing something, but how are we formatting the Tailwind class names? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uhh, this is a particularly nasty string of class names. it wraps across 4 lines on my enormous screen and immediately triggers my "this is incomprehensible and I should run away" reflex. how could we refactor this to be clearer? maybe for things with lots of complicated selectors like this we should stick with emotion actually? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All this is really doing is styling the underlying There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, to be clear – I think this is an area where the Tailwind abstractions break down – definitely not the fault of anyone here. I understand why the code is the way it is:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of how it looks, but if we can shove all the nastiness into a corner and put a nice bow on it, I think it's fine enough Getting back to my original question, though: what tools do we have to sort the class names automatically? The syntax is bad enough, but if we can't even order the styles by the order that they're applying in, this will be a nightmare to debug There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doing the class sorting is a solved problem when using prettier. Its a work in progress with biome as discussed here. biomejs/biome#1274 |
||
{children} | ||
</Command> | ||
</DialogContent> | ||
</Dialog> | ||
); | ||
}; | ||
|
||
const CommandInput = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.Input>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> | ||
>(({ className, ...props }, ref) => ( | ||
<div className="flex items-center border-b px-3" cmdk-input-wrapper=""> | ||
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" /> | ||
<CommandPrimitive.Input | ||
ref={ref} | ||
className={cn( | ||
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-content-secondary disabled:cursor-not-allowed disabled:opacity-50", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
</div> | ||
)); | ||
|
||
CommandInput.displayName = CommandPrimitive.Input.displayName; | ||
|
||
const CommandList = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.List>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List> | ||
>(({ className, ...props }, ref) => ( | ||
<CommandPrimitive.List | ||
ref={ref} | ||
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)} | ||
{...props} | ||
/> | ||
)); | ||
|
||
CommandList.displayName = CommandPrimitive.List.displayName; | ||
|
||
const CommandEmpty = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.Empty>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty> | ||
>((props, ref) => ( | ||
<CommandPrimitive.Empty | ||
ref={ref} | ||
className="py-6 text-center text-sm" | ||
{...props} | ||
/> | ||
)); | ||
|
||
CommandEmpty.displayName = CommandPrimitive.Empty.displayName; | ||
|
||
const CommandGroup = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.Group>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group> | ||
>(({ className, ...props }, ref) => ( | ||
<CommandPrimitive.Group | ||
ref={ref} | ||
className={cn( | ||
"overflow-hidden p-1 text-content-primary [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-content-secondary", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
)); | ||
|
||
CommandGroup.displayName = CommandPrimitive.Group.displayName; | ||
|
||
const CommandSeparator = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.Separator>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator> | ||
>(({ className, ...props }, ref) => ( | ||
<CommandPrimitive.Separator | ||
ref={ref} | ||
className={cn("-mx-1 h-px bg-border", className)} | ||
{...props} | ||
/> | ||
)); | ||
CommandSeparator.displayName = CommandPrimitive.Separator.displayName; | ||
|
||
const CommandItem = React.forwardRef< | ||
React.ElementRef<typeof CommandPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item> | ||
>(({ className, ...props }, ref) => ( | ||
<CommandPrimitive.Item | ||
ref={ref} | ||
className={cn( | ||
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-surface-secondary data-[selected=true]:text-content-primary data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
)); | ||
|
||
CommandItem.displayName = CommandPrimitive.Item.displayName; | ||
|
||
const CommandShortcut = ({ | ||
className, | ||
...props | ||
}: React.HTMLAttributes<HTMLSpanElement>) => { | ||
return ( | ||
<span | ||
className={cn( | ||
"ml-auto text-xs tracking-widest text-muted-foreground", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
); | ||
}; | ||
CommandShortcut.displayName = "CommandShortcut"; | ||
|
||
export { | ||
Command, | ||
CommandDialog, | ||
CommandInput, | ||
CommandList, | ||
CommandEmpty, | ||
CommandGroup, | ||
CommandItem, | ||
CommandShortcut, | ||
CommandSeparator, | ||
}; | ||
jaaydenh marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.