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
#1685 Custom options for @pixiebrix/data/get and @pixiebrix/data/put bricks #1750
Conversation
import React from "react"; | ||
import { Button } from "react-bootstrap"; | ||
|
||
type MenuListWithAddButtonProps = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're not exporting the component and there's just one component in the file, I think it's OK to use "OwnProps" or another short type name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases the props type is called {ComponentName}Props
. It always makes a naming pair of component-props and does not depend on exported members.
I'm for consistency. Why not to settle on the convention now. Options:
- Do not define a type at all unless you need to export... or the type definition is huge (10+ line) example.
- Always define the props type. Call it
OwnProps
if not exported, call it{ComponentName}Props
if/when you export the type. - Always define the props type and call it
{ComponentName}Props
.
@twschiller
cc @BLoe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thoughts are that if the type is not exported, I don't much care what you name it, I care much, much more about how the type is structured, so I can read it and understand what's going on with a component.
If it's exported it should be {ComponentName}Props
, that's about the only strict rule I'd feel strongly about here.
}); | ||
|
||
if ("error" in result) { | ||
console.error(result.error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Fix error handling
|
||
const [addDatabaseToGroup] = useAddDatabaseToGroupMutation(); | ||
|
||
const onSave = async ({ name, organizationId, groupId }: DatabaseConfig) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See useUserAction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appBaseQuery
doesn't throw, it returns a result with an error ->useUserAction
will not handle the error properly.useUserAction
tries to get the error message from AxiosError, butappBaseQuery
kinda obfurscates the error ->useUserAction
logic doesn't help.onSave
conditionally makes 2 requests and handles the result of each. There's no need to update the UI state either.
Not sure howuseUserAction
can help here?
}), | ||
getOrganizations: builder.query<Organization[], void>({ | ||
query: () => ({ url: "/api/organizations/", method: "get" }), | ||
providesTags: ["Organizations"], | ||
transformResponse: ( | ||
baseQueryReturnValue: Array<components["schemas"]["Organization"]> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've been referring to the type exported from the the contract.ts file instead of using components["schema"]
in code
Also, make any manual updates to the schema in contracts.ts
instead of using any below. See the examples in contract.ts that use "&" to refine the types from swagger.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make any manual updates to the schema in contracts.ts
This is my intention.
API returns Organization
without isAdmin
(or role
) property. src/types/contract.ts
add it at line 40. But this is only on the types level.
Here transformResponse
reserves the object from API (which is actually of type Array<components["schemas"]["Organization"]>
) and converts it to what we want in the Extension project - Organization
defined in contracts.ts
.
src/services/api.ts
Outdated
): Organization[] => | ||
baseQueryReturnValue.map((apiOrganization) => ({ | ||
...apiOrganization, | ||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use //-style comments. Your IDE should have a shortcut for commenting multiple lines
src/services/api.ts
Outdated
meta: { organizationId }, | ||
includeRequestData: true, | ||
}), | ||
providesTags: ["Groups"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't these tags need to include the id of the organization? https://redux-toolkit.js.org/rtk-query/api/createApi#providestags. Or does the meta automatically handle that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meta is a means of getting request parameter in the transformResponse
function.
I think you're right, the organization id should be included in tags.
const onSave = async ({ name, organizationId, groupId }: DatabaseConfig) => { | ||
const result = await createDatabase({ | ||
name, | ||
organizationId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is organizationId "" at this point? Or is it null? See comment on the type definition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
organizationId
can be an ID or empty (null, undefined, blank).
onClose(); | ||
}; | ||
|
||
let organizationOptions = (organizations || []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extract into helper method, e.g., selectOrganizationOptions(organizations)
Use the null coalescing operator ??
, not ||
(o) => o.id === db.organization_id | ||
); | ||
const dbName = organization | ||
? `${db.name} [${organization.name}]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See http://github.com/pixiebrix/pixiebrix-extension/blob/feature/1685-data-get-put/src/hooks/auth.ts#L114-L114 for our current convention for showing organization name in options drop downs (it uses an mdash)
@@ -78,6 +80,9 @@ const SelectWidget = <TOption extends Option<TOption["value"]>>({ | |||
>); | |||
}; | |||
|
|||
const selectValue = | |||
options?.find((option: TOption) => value === option.value) || null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the null coalescing operator ??, not ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BALEHOK this is ready to merge once you make one small improvement
- When you add a database with create database, it should be selected from the dropdown
Also, some general comments:
- Use the nullish coalescing operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
- The
role
logic is sufficient but isn't completely correct because it doesn't account for the Developer or Restricted team roles. I added a warning in both places about role so that someone in the future doesn't make a mistake with them
organizationId: string | null; | ||
|
||
/** | ||
* Id of a Group for shared DB. | ||
* Blank for a Personal DB | ||
* UUID of a Group for a shared DB, or null/empty for a personal DB. | ||
*/ | ||
groupId: string; | ||
groupId: string | null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twschiller This refers to the rule strictNullChecks
. It is disabled so any property can be null
or undefined
. Seems that <type> | null
is not really consistent with the code style, it isn't widely adopted on the project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This refers to the rule strictNullChecks
I'm not sure I'm following? Even though strictNullChecks is not enabled, we've always been marking which fields are optional with the (?) or accept null. Otherwise the type is inconsistent with the documentation above it
Resolves #1685
DB Selector
Create DB modal