Skip to content

Commit

Permalink
Checkbox updates (#6448)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown authored Sep 10, 2021
1 parent 8388452 commit c2b124f
Show file tree
Hide file tree
Showing 35 changed files with 370 additions and 101 deletions.
46 changes: 46 additions & 0 deletions .changeset/rare-baboons-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
'@keystone-next/keystone': major
---

The `checkbox` field is now non-nullable in the database, if you need three states, you should use `select()`. The field no longer accepts dynamic default values and it will default to `false` unless a different `defaultValue` is specified. `graphql.isNonNull` can also be set if you have no read access control and you don't intend to add any in the future, it will make the GraphQL output field non-nullable.

If you're using SQLite, Prisma will generate a migration that makes the column non-nullable and sets any rows that have

If you're using PostgreSQL, Prisma will generate a migration but you'll need to modify it if you have nulls in a checkbox field. Keystone will say that the migration cannot be executed:

```
✨ Starting Keystone
⭐️ Dev Server Ready on http://localhost:3000
✨ Generating GraphQL and Prisma schemas
✨ There has been a change to your Keystone schema that requires a migration
⚠️ We found changes that cannot be executed:
• Made the column `isAdmin` on table `User` required, but there are 1 existing NULL values.
✔ Name of migration … make-is-admin-non-null
✨ A migration has been created at migrations/20210906053141_make_is_admin_non_null
Please edit the migration and run keystone-next dev again to apply the migration
```

The generated migration will look like this:

```sql
/*
Warnings:
- Made the column `isAdmin` on table `User` required. This step will fail if there are existing NULL values in that column.
*/
-- AlterTable
ALTER TABLE "User" ALTER COLUMN "isAdmin" SET NOT NULL,
ALTER COLUMN "isAdmin" SET DEFAULT false;
```

To make it set any null values to false in your database, you need to modify it so that it looks like this but with the table and column names replaced.

```sql
ALTER TABLE "User" ALTER COLUMN "isAdmin" SET DEFAULT false;
UPDATE "User" SET "isAdmin" = DEFAULT WHERE "isAdmin" IS NULL;
ALTER TABLE "User" ALTER COLUMN "isAdmin" SET NOT NULL;
```
23 changes: 17 additions & 6 deletions docs/pages/docs/apis/fields.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,15 @@ A `checkbox` field represents a boolean (`true`/`false`) value.

Options:

- `defaultValue` (default: `undefined`): Can be either a boolean value or an async function which takes an argument `({ context, originalInput })` and returns a boolean value.
This value will be used for the field when creating items if no explicit value is set.
`context` is a [`KeystoneContext`](./context) object.
`originalInput` is an object containing the data passed in to the `create` mutation.
- `isRequired` (default: `false`): If `true` then this field can never be set to `null`.
- `defaultValue` (default: `false`): This value will be used for the field when creating items if no explicit value is set.
- `graphql.read.isNonNull` (default: `false`): If you have no read access control and you don't intend to add any in the future,
you can set this to true and the output field will be non-nullable. This is only allowed when you have no read access control because otherwise,
when access is denied, `null` will be returned which will cause an error since the field is non-nullable and the error
will propagate up until a nullable field is found which means the entire item will be unreadable and when doing an `items` query, all the items will be unreadable.
- `graphql.create.isNonNull` (default: `false`): If you have no create access control and you want to explicitly show that this is field is non-nullable in the create input
you can set this to true and the create field will be non-nullable and have a default value at the GraphQL level.
This is only allowed when you have no create access control because otherwise, the item will always fail access control
if a user doesn't have access to create the particular field regardless of whether or not they specify the field in the create.

```typescript
import { config, createSchema, list } from '@keystone-next/keystone';
Expand All @@ -153,7 +157,14 @@ export default config({
fields: {
fieldName: checkbox({
defaultValue: true,
isRequired: true,
graphql: {
read: {
isNonNull: true
},
create: {
isNonNull: true
},
}
}),
/* ... */
},
Expand Down
6 changes: 3 additions & 3 deletions examples-staging/auth/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ generator client {
}

model User {
id String @id @default(cuid())
id String @id @default(cuid())
name String?
email String? @unique
email String? @unique
password String?
isAdmin Boolean?
isAdmin Boolean @default(false)
}
2 changes: 1 addition & 1 deletion examples-staging/basic/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ model User {
attachment_mode String?
attachment_filename String?
password String?
isAdmin Boolean?
isAdmin Boolean @default(false)
roles String?
phoneNumbers PhoneNumber[] @relation("PhoneNumber_user")
posts Post[] @relation("Post_author")
Expand Down
16 changes: 8 additions & 8 deletions examples-staging/ecommerce/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ model Order {
}

model Role {
id String @id @default(cuid())
id String @id @default(cuid())
name String?
canManageProducts Boolean?
canSeeOtherUsers Boolean?
canManageUsers Boolean?
canManageRoles Boolean?
canManageCart Boolean?
canManageOrders Boolean?
assignedTo User[] @relation("User_role")
canManageProducts Boolean @default(false)
canSeeOtherUsers Boolean @default(false)
canManageUsers Boolean @default(false)
canManageRoles Boolean @default(false)
canManageCart Boolean @default(false)
canManageOrders Boolean @default(false)
assignedTo User[] @relation("User_role")
}
22 changes: 11 additions & 11 deletions examples-staging/roles/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ generator client {
}

model Todo {
id String @id @default(cuid())
id String @id @default(cuid())
label String?
isComplete Boolean?
isPrivate Boolean?
assignedTo Person? @relation("Todo_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
isComplete Boolean @default(false)
isPrivate Boolean @default(false)
assignedTo Person? @relation("Todo_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
@@index([assignedToId])
}
Expand All @@ -37,11 +37,11 @@ model Person {
model Role {
id String @id @default(cuid())
name String?
canCreateTodos Boolean?
canManageAllTodos Boolean?
canSeeOtherPeople Boolean?
canEditOtherPeople Boolean?
canManagePeople Boolean?
canManageRoles Boolean?
canCreateTodos Boolean @default(false)
canManageAllTodos Boolean @default(false)
canSeeOtherPeople Boolean @default(false)
canEditOtherPeople Boolean @default(false)
canManagePeople Boolean @default(false)
canManageRoles Boolean @default(false)
assignedTo Person[] @relation("Person_role")
}
2 changes: 1 addition & 1 deletion examples-staging/sandbox/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ generator client {
model Todo {
id String @id @default(cuid())
label String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo User? @relation("Todo_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/custom-admin-ui-logo/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -78,9 +78,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-admin-ui-logo/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/custom-admin-ui-navigation/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -78,9 +78,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-admin-ui-navigation/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/custom-admin-ui-pages/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -78,9 +78,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-admin-ui-pages/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/custom-field-view/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -79,9 +79,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-field-view/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/default-values/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -78,9 +78,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/default-values/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
8 changes: 4 additions & 4 deletions examples/json/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ generator client {
}

model Package {
id String @id @default(cuid())
id String @id @default(cuid())
label String?
pkgjson String?
isPrivate Boolean?
ownedBy Person? @relation("Package_ownedBy", fields: [ownedById], references: [id])
ownedById String? @map("ownedBy")
isPrivate Boolean @default(false)
ownedBy Person? @relation("Package_ownedBy", fields: [ownedById], references: [id])
ownedById String? @map("ownedBy")
@@index([ownedById])
}
Expand Down
6 changes: 3 additions & 3 deletions examples/task-manager/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -78,9 +78,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
2 changes: 1 addition & 1 deletion examples/task-manager/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ model Task {
id String @id @default(cuid())
label String?
priority String?
isComplete Boolean?
isComplete Boolean @default(false)
assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id])
assignedToId String? @map("assignedTo")
finishBy DateTime?
Expand Down
6 changes: 3 additions & 3 deletions examples/testing/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ input TaskWhereInput {
id: IDFilter
label: StringNullableFilter
priority: TaskPriorityTypeNullableFilter
isComplete: BooleanNullableFilter
isComplete: BooleanFilter
assignedTo: PersonWhereInput
finishBy: DateTimeNullableFilter
}
Expand Down Expand Up @@ -131,9 +131,9 @@ input TaskPriorityTypeNullableFilter {
not: TaskPriorityTypeNullableFilter
}

input BooleanNullableFilter {
input BooleanFilter {
equals: Boolean
not: BooleanNullableFilter
not: BooleanFilter
}

input DateTimeNullableFilter {
Expand Down
Loading

0 comments on commit c2b124f

Please sign in to comment.