Merge pull request #13 from Irev-Dev/dev
merge in dev
This commit was merged in pull request #13.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# Migration `20201018233330-add-simple-user-model`
|
||||
|
||||
This migration has been generated by Kurt Hutten at 10/19/2020, 10:33:30 AM.
|
||||
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||
|
||||
## Database Steps
|
||||
|
||||
```sql
|
||||
CREATE TABLE "User" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"userName" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"issuer" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
"image" TEXT,
|
||||
"bio" TEXT
|
||||
)
|
||||
|
||||
CREATE UNIQUE INDEX "User.userName_unique" ON "User"("userName")
|
||||
|
||||
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email")
|
||||
|
||||
CREATE UNIQUE INDEX "User.issuer_unique" ON "User"("issuer")
|
||||
```
|
||||
|
||||
## Changes
|
||||
|
||||
```diff
|
||||
diff --git schema.prisma schema.prisma
|
||||
migration 20201011095227-create-contact..20201018233330-add-simple-user-model
|
||||
--- datamodel.dml
|
||||
+++ datamodel.dml
|
||||
@@ -1,9 +1,7 @@
|
||||
datasource DS {
|
||||
- // optionally set multiple providers
|
||||
- // example: provider = ["sqlite", "postgresql"]
|
||||
- provider = "sqlite"
|
||||
- url = "***"
|
||||
+ provider = ["sqlite", "postgresql"]
|
||||
+ url = "***"
|
||||
}
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
@@ -34,4 +32,17 @@
|
||||
email String
|
||||
message String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
+
|
||||
+model User {
|
||||
+ id Int @id @default(autoincrement())
|
||||
+ userName String @unique
|
||||
+ email String @unique
|
||||
+ issuer String @unique
|
||||
+
|
||||
+ createdAt DateTime @default(now())
|
||||
+ updatedAt DateTime @updatedAt
|
||||
+
|
||||
+ image String? // url maybe id or file storage service? cloudinary?
|
||||
+ bio String? //mark down
|
||||
+}
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
datasource DS {
|
||||
provider = ["sqlite", "postgresql"]
|
||||
url = "***"
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = "native"
|
||||
}
|
||||
|
||||
model Post {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
body String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Part {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String // markdown string
|
||||
code String @default("// Welcome to Cascade Studio! Here are some useful functions:\n// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()\n// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()\n// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),\n// FilletEdges(), ChamferEdges(),\n// Slider(), Button(), Checkbox()\nlet holeRadius = Slider(\"Radius\", 30 , 20 , 40);\nlet sphere = Sphere(50);\nlet cylinderZ = Cylinder(holeRadius, 200, true);\nlet cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));\nlet cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));\nTranslate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));\n\nTranslate([-25, 0, 40], Text3D(\"Hi!\"));\n// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!")
|
||||
mainImage String // link to cloudinary
|
||||
createdAt DateTime @default(now())
|
||||
// userId
|
||||
//likes, comments, reactions
|
||||
}
|
||||
|
||||
model Contact {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
email String
|
||||
message String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
userName String @unique
|
||||
email String @unique
|
||||
issuer String @unique
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
image String? // url maybe id or file storage service? cloudinary?
|
||||
bio String? //mark down
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
{
|
||||
"version": "0.3.14-fixed",
|
||||
"steps": [
|
||||
{
|
||||
"tag": "UpdateArgument",
|
||||
"location": {
|
||||
"tag": "Source",
|
||||
"source": "DS"
|
||||
},
|
||||
"argument": "provider",
|
||||
"newValue": "[\"sqlite\", \"postgresql\"]"
|
||||
},
|
||||
{
|
||||
"tag": "CreateModel",
|
||||
"model": "User"
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "id",
|
||||
"type": "Int",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "id"
|
||||
},
|
||||
"directive": "id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "id"
|
||||
},
|
||||
"directive": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateArgument",
|
||||
"location": {
|
||||
"tag": "Directive",
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "id"
|
||||
},
|
||||
"directive": "default"
|
||||
},
|
||||
"argument": "",
|
||||
"value": "autoincrement()"
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "userName",
|
||||
"type": "String",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "userName"
|
||||
},
|
||||
"directive": "unique"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "email",
|
||||
"type": "String",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "email"
|
||||
},
|
||||
"directive": "unique"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "issuer",
|
||||
"type": "String",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "issuer"
|
||||
},
|
||||
"directive": "unique"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "createdAt",
|
||||
"type": "DateTime",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "createdAt"
|
||||
},
|
||||
"directive": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateArgument",
|
||||
"location": {
|
||||
"tag": "Directive",
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "createdAt"
|
||||
},
|
||||
"directive": "default"
|
||||
},
|
||||
"argument": "",
|
||||
"value": "now()"
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "updatedAt",
|
||||
"type": "DateTime",
|
||||
"arity": "Required"
|
||||
},
|
||||
{
|
||||
"tag": "CreateDirective",
|
||||
"location": {
|
||||
"path": {
|
||||
"tag": "Field",
|
||||
"model": "User",
|
||||
"field": "updatedAt"
|
||||
},
|
||||
"directive": "updatedAt"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "image",
|
||||
"type": "String",
|
||||
"arity": "Optional"
|
||||
},
|
||||
{
|
||||
"tag": "CreateField",
|
||||
"model": "User",
|
||||
"field": "bio",
|
||||
"type": "String",
|
||||
"arity": "Optional"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
# Migration `20201019072122-add-simplify-user-model`
|
||||
|
||||
This migration has been generated by Kurt Hutten at 10/19/2020, 6:21:22 PM.
|
||||
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||
|
||||
## Database Steps
|
||||
|
||||
```sql
|
||||
DROP INDEX "User.issuer_unique"
|
||||
|
||||
DROP INDEX "User.userName_unique"
|
||||
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_User" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"email" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
"image" TEXT,
|
||||
"bio" TEXT
|
||||
);
|
||||
INSERT INTO "new_User" ("id", "email", "createdAt", "updatedAt", "image", "bio") SELECT "id", "email", "createdAt", "updatedAt", "image", "bio" FROM "User";
|
||||
DROP TABLE "User";
|
||||
ALTER TABLE "new_User" RENAME TO "User";
|
||||
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON
|
||||
```
|
||||
|
||||
## Changes
|
||||
|
||||
```diff
|
||||
diff --git schema.prisma schema.prisma
|
||||
migration 20201018233330-add-simple-user-model..20201019072122-add-simplify-user-model
|
||||
--- datamodel.dml
|
||||
+++ datamodel.dml
|
||||
@@ -1,7 +1,7 @@
|
||||
datasource DS {
|
||||
provider = ["sqlite", "postgresql"]
|
||||
- url = "***"
|
||||
+ url = "***"
|
||||
}
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
@@ -34,12 +34,12 @@
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
model User {
|
||||
- id Int @id @default(autoincrement())
|
||||
- userName String @unique
|
||||
- email String @unique
|
||||
- issuer String @unique
|
||||
+ id Int @id @default(autoincrement())
|
||||
+ email String @unique
|
||||
+ // userName String @unique
|
||||
+ // issuer String @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
datasource DS {
|
||||
provider = ["sqlite", "postgresql"]
|
||||
url = "***"
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = "native"
|
||||
}
|
||||
|
||||
model Post {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
body String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Part {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String // markdown string
|
||||
code String @default("// Welcome to Cascade Studio! Here are some useful functions:\n// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()\n// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()\n// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),\n// FilletEdges(), ChamferEdges(),\n// Slider(), Button(), Checkbox()\nlet holeRadius = Slider(\"Radius\", 30 , 20 , 40);\nlet sphere = Sphere(50);\nlet cylinderZ = Cylinder(holeRadius, 200, true);\nlet cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));\nlet cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));\nTranslate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));\n\nTranslate([-25, 0, 40], Text3D(\"Hi!\"));\n// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!")
|
||||
mainImage String // link to cloudinary
|
||||
createdAt DateTime @default(now())
|
||||
// userId
|
||||
//likes, comments, reactions
|
||||
}
|
||||
|
||||
model Contact {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
email String
|
||||
message String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
// userName String @unique
|
||||
// issuer String @unique
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
image String? // url maybe id or file storage service? cloudinary?
|
||||
bio String? //mark down
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "0.3.14-fixed",
|
||||
"steps": [
|
||||
{
|
||||
"tag": "DeleteField",
|
||||
"model": "User",
|
||||
"field": "userName"
|
||||
},
|
||||
{
|
||||
"tag": "DeleteField",
|
||||
"model": "User",
|
||||
"field": "issuer"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,4 +4,6 @@
|
||||
20201011043647-create-parts
|
||||
20201011052155-add-code-to-part
|
||||
20201011082558-add-code-not-needed-upon-create
|
||||
20201011095227-create-contact
|
||||
20201011095227-create-contact
|
||||
20201018233330-add-simple-user-model
|
||||
20201019072122-add-simplify-user-model
|
||||
@@ -33,3 +33,16 @@ model Contact {
|
||||
message String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
// userName String @unique
|
||||
// issuer String @unique
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
image String? // url maybe id or file storage service? cloudinary?
|
||||
bio String? //mark down
|
||||
}
|
||||
|
||||
35
api/src/functions/identity-signup.js
Normal file
35
api/src/functions/identity-signup.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { createUser } from 'src/services/users/users.js'
|
||||
|
||||
export const handler = async (req, _context) => {
|
||||
const body = JSON.parse(req.body)
|
||||
console.log(body)
|
||||
console.log(_context)
|
||||
|
||||
const eventType = body.event
|
||||
const user = body.user
|
||||
const email = user.email
|
||||
|
||||
let roles = []
|
||||
|
||||
if (eventType === 'signup') {
|
||||
roles.push('user')
|
||||
const hi = {
|
||||
email: 'kurt.hutten@gmail.com',
|
||||
image: '',
|
||||
bio: ''
|
||||
}
|
||||
const input = {
|
||||
email,
|
||||
}
|
||||
createUser({input})
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({ app_metadata: { roles: roles } }),
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
statusCode: 200,
|
||||
}
|
||||
}
|
||||
}
|
||||
35
api/src/graphql/users.sdl.js
Normal file
35
api/src/graphql/users.sdl.js
Normal file
@@ -0,0 +1,35 @@
|
||||
export const schema = gql`
|
||||
type User {
|
||||
id: Int!
|
||||
email: String!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
image: String
|
||||
bio: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
users: [User!]!
|
||||
user(id: Int!): User
|
||||
}
|
||||
|
||||
input CreateUserInput {
|
||||
email: String!
|
||||
issuer: String!
|
||||
image: String
|
||||
bio: String
|
||||
}
|
||||
|
||||
input UpdateUserInput {
|
||||
email: String
|
||||
issuer: String
|
||||
image: String
|
||||
bio: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createUser(input: CreateUserInput!): User!
|
||||
updateUser(id: Int!, input: UpdateUserInput!): User!
|
||||
deleteUser(id: Int!): User!
|
||||
}
|
||||
`
|
||||
38
api/src/services/users/users.js
Normal file
38
api/src/services/users/users.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { db } from 'src/lib/db'
|
||||
import { requireAuth } from 'src/lib/auth'
|
||||
|
||||
export const users = () => {
|
||||
requireAuth({ role: 'admin' })
|
||||
return db.user.findMany()
|
||||
}
|
||||
|
||||
export const user = ({ id }) => {
|
||||
requireAuth()
|
||||
return db.user.findOne({
|
||||
where: { id },
|
||||
})
|
||||
}
|
||||
|
||||
export const createUser = ({ input }) => {
|
||||
console.log(input)
|
||||
console.log(JSON.stringify(input))
|
||||
requireAuth({ role: 'admin' })
|
||||
return db.user.create({
|
||||
data: input,
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUser = ({ id, input }) => {
|
||||
requireAuth()
|
||||
return db.user.update({
|
||||
data: input,
|
||||
where: { id },
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteUser = ({ id }) => {
|
||||
requireAuth({ role: 'admin' })
|
||||
return db.user.delete({
|
||||
where: { id },
|
||||
})
|
||||
}
|
||||
9
api/src/services/users/users.test.js
Normal file
9
api/src/services/users/users.test.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
import { users } from './users'
|
||||
*/
|
||||
|
||||
describe('users', () => {
|
||||
it('returns true', () => {
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -28,6 +28,8 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"rich-markdown-editor": "^11.0.2",
|
||||
"styled-components": "^5.2.0",
|
||||
"three": "^0.118.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -12,9 +12,19 @@ import { Router, Route, Private } from '@redwoodjs/router'
|
||||
const Routes = () => {
|
||||
return (
|
||||
<Router>
|
||||
{/* TODO add add min role to users and users/new */}
|
||||
<Private unauthenticated="home" role="admin">
|
||||
<Route path="/users" page={UsersPage} name="users" />
|
||||
<Route path="/users/new" page={NewUserPage} name="newUser" />
|
||||
</Private>
|
||||
<Private unauthenticated="home">
|
||||
<Route path="/users/{id:Int}/edit" page={EditUserPage} name="editUser" />
|
||||
</Private>
|
||||
<Route path="/users/{id:Int}" page={UserPage} name="user" />
|
||||
<Route path="/contact" page={ContactPage} name="contact" />
|
||||
<Route path="/parts/new" page={NewPartPage} name="newPart" />
|
||||
<Route path="/parts/{id:Int}/edit" page={EditPartPage} name="editPart" />
|
||||
<Route path="/parts/{id:Int}/ide" page={IdePartPage} name="partIde" />
|
||||
<Route path="/parts/{id:Int}" page={PartPage} name="part" />
|
||||
<Route path="/parts" page={PartsPage} name="parts" />
|
||||
<Route path="/blog-post/{id:Int}" page={BlogPostPage} name="blogPost" />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import { useMutation } from '@redwoodjs/web'
|
||||
import PartForm from 'src/components/PartForm'
|
||||
|
||||
export const QUERY = gql`
|
||||
@@ -26,26 +25,11 @@ const UPDATE_PART_MUTATION = gql`
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Success = ({ part }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [updatePart, { loading, error }] = useMutation(UPDATE_PART_MUTATION, {
|
||||
onCompleted: () => {
|
||||
navigate(routes.parts())
|
||||
addMessage('Part updated.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
const [updatePart, { loading, error }] = useMutation(UPDATE_PART_MUTATION)
|
||||
|
||||
const onSave = (input, id) => {
|
||||
updatePart({ variables: { id, input } })
|
||||
}
|
||||
const onSave = (input, id) => updatePart({ variables: { id, input } })
|
||||
|
||||
return (
|
||||
<div className="rw-segment">
|
||||
<header className="rw-segment-header">
|
||||
<h2 className="rw-heading rw-heading-secondary">Edit Part {part.id}</h2>
|
||||
</header>
|
||||
<div className="rw-segment-main">
|
||||
<PartForm part={part} onSave={onSave} error={error} loading={loading} />
|
||||
</div>
|
||||
</div>
|
||||
<PartForm part={part} onSave={onSave} error={error} loading={loading} />
|
||||
)
|
||||
}
|
||||
|
||||
50
web/src/components/EditUserCell/EditUserCell.js
Normal file
50
web/src/components/EditUserCell/EditUserCell.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import UserForm from 'src/components/UserForm'
|
||||
|
||||
export const QUERY = gql`
|
||||
query FIND_USER_BY_ID($id: Int!) {
|
||||
user: user(id: $id) {
|
||||
id
|
||||
email
|
||||
createdAt
|
||||
updatedAt
|
||||
image
|
||||
bio
|
||||
}
|
||||
}
|
||||
`
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation UpdateUserMutation($id: Int!, $input: UpdateUserInput!) {
|
||||
updateUser(id: $id, input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Success = ({ user }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [updateUser, { loading, error }] = useMutation(UPDATE_USER_MUTATION, {
|
||||
onCompleted: () => {
|
||||
navigate(routes.users())
|
||||
addMessage('User updated.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
|
||||
const onSave = (input, id) => {
|
||||
updateUser({ variables: { id, input } })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-segment">
|
||||
<header className="rw-segment-header">
|
||||
<h2 className="rw-heading rw-heading-secondary">Edit User {user.id}</h2>
|
||||
</header>
|
||||
<div className="rw-segment-main">
|
||||
<UserForm user={user} onSave={onSave} error={error} loading={loading} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
46
web/src/components/IdePartCell/IdePartCell.js
Normal file
46
web/src/components/IdePartCell/IdePartCell.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import Part from 'src/components/Part'
|
||||
|
||||
export const QUERY = gql`
|
||||
query FIND_PART_BY_ID($id: Int!) {
|
||||
part: part(id: $id) {
|
||||
id
|
||||
title
|
||||
description
|
||||
code
|
||||
mainImage
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const UPDATE_PART_MUTATION = gql`
|
||||
mutation UpdatePartMutation($id: Int!, $input: UpdatePartInput!) {
|
||||
updatePart(id: $id, input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => <div>Part not found</div>
|
||||
|
||||
export const Success = ({ part }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [updatePart, { loading, error }] = useMutation(UPDATE_PART_MUTATION, {
|
||||
onCompleted: () => {
|
||||
// navigate(routes.part({id: updatePart.id}))
|
||||
addMessage('Part updated.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
console.log({updatePart})
|
||||
|
||||
|
||||
const saveCode = (input, id) => {
|
||||
console.log(id, input, 'wowow')
|
||||
updatePart({ variables: { id, input } })
|
||||
}
|
||||
return <Part part={{...part, code: part.code}} saveCode={saveCode} loading={loading} error={error} />
|
||||
}
|
||||
6
web/src/components/IdePartCell/IdePartCell.mock.js
Normal file
6
web/src/components/IdePartCell/IdePartCell.mock.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// Define your own mock data here:
|
||||
export const standard = (/* vars, { ctx, req } */) => ({
|
||||
idePart: {
|
||||
id: 42,
|
||||
},
|
||||
})
|
||||
20
web/src/components/IdePartCell/IdePartCell.stories.js
Normal file
20
web/src/components/IdePartCell/IdePartCell.stories.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Loading, Empty, Failure, Success } from './IdePartCell'
|
||||
import { standard } from './IdePartCell.mock'
|
||||
|
||||
export const loading = () => {
|
||||
return Loading ? <Loading /> : null
|
||||
}
|
||||
|
||||
export const empty = () => {
|
||||
return Empty ? <Empty /> : null
|
||||
}
|
||||
|
||||
export const failure = () => {
|
||||
return Failure ? <Failure error={new Error('Oh no')} /> : null
|
||||
}
|
||||
|
||||
export const success = () => {
|
||||
return Success ? <Success {...standard()} /> : null
|
||||
}
|
||||
|
||||
export default { title: 'Cells/IdePartCell' }
|
||||
26
web/src/components/IdePartCell/IdePartCell.test.js
Normal file
26
web/src/components/IdePartCell/IdePartCell.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { render, screen } from '@redwoodjs/testing'
|
||||
import { Loading, Empty, Failure, Success } from './IdePartCell'
|
||||
import { standard } from './IdePartCell.mock'
|
||||
|
||||
describe('IdePartCell', () => {
|
||||
test('Loading renders successfully', () => {
|
||||
render(<Loading />)
|
||||
// Use screen.debug() to see output
|
||||
expect(screen.getByText('Loading...')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Empty renders successfully', async () => {
|
||||
render(<Empty />)
|
||||
expect(screen.getByText('Empty')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Failure renders successfully', async () => {
|
||||
render(<Failure error={new Error('Oh no')} />)
|
||||
expect(screen.getByText(/Oh no/i)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Success renders successfully', async () => {
|
||||
render(<Success idePart={standard().idePart} />)
|
||||
expect(screen.getByText(/42/i)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
38
web/src/components/NewUser/NewUser.js
Normal file
38
web/src/components/NewUser/NewUser.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import UserForm from 'src/components/UserForm'
|
||||
|
||||
const CREATE_USER_MUTATION = gql`
|
||||
mutation CreateUserMutation($input: CreateUserInput!) {
|
||||
createUser(input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const NewUser = () => {
|
||||
const { addMessage } = useFlash()
|
||||
const [createUser, { loading, error }] = useMutation(CREATE_USER_MUTATION, {
|
||||
onCompleted: () => {
|
||||
navigate(routes.users())
|
||||
addMessage('User created.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
|
||||
const onSave = (input) => {
|
||||
createUser({ variables: { input } })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-segment">
|
||||
<header className="rw-segment-header">
|
||||
<h2 className="rw-heading rw-heading-secondary">New User</h2>
|
||||
</header>
|
||||
<div className="rw-segment-main">
|
||||
<UserForm onSave={onSave} loading={loading} error={error} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default NewUser
|
||||
@@ -1,46 +1,32 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import Part from 'src/components/Part'
|
||||
|
||||
export const QUERY = gql`
|
||||
query FIND_PART_BY_ID($id: Int!) {
|
||||
part: part(id: $id) {
|
||||
id
|
||||
title
|
||||
description
|
||||
code
|
||||
mainImage
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`
|
||||
import {QUERY as reExportQuery} from 'src/components/EditPartCell'
|
||||
import Editor from "rich-markdown-editor";
|
||||
|
||||
const UPDATE_PART_MUTATION = gql`
|
||||
mutation UpdatePartMutation($id: Int!, $input: UpdatePartInput!) {
|
||||
updatePart(id: $id, input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
export const QUERY = reExportQuery
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => <div>Part not found</div>
|
||||
export const Empty = () => <div>Empty</div>
|
||||
|
||||
export const Failure = ({ error }) => <div>Error: {error.message}</div>
|
||||
|
||||
export const Success = ({ part }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [updatePart, { loading, error }] = useMutation(UPDATE_PART_MUTATION, {
|
||||
onCompleted: () => {
|
||||
// navigate(routes.part({id: updatePart.id}))
|
||||
addMessage('Part updated.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
console.log({updatePart})
|
||||
|
||||
|
||||
const saveCode = (input, id) => {
|
||||
console.log(id, input, 'wowow')
|
||||
updatePart({ variables: { id, input } })
|
||||
}
|
||||
return <Part part={{...part, code: part.code}} saveCode={saveCode} loading={loading} error={error} />
|
||||
console.log(part)
|
||||
return (
|
||||
<>
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-center">
|
||||
<img src={part.mainImage} />
|
||||
</div>
|
||||
<div className="bg-white p-8 my-12 min-h-md">
|
||||
<h2 className="text-4xl py-4">{part.title}</h2>
|
||||
<Editor
|
||||
className="markdown-overrides"
|
||||
defaultValue={part.description}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,14 +7,32 @@ import {
|
||||
TextAreaField,
|
||||
Submit,
|
||||
} from '@redwoodjs/forms'
|
||||
import { useState } from 'react';
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
import { useFlash } from '@redwoodjs/web'
|
||||
|
||||
import Editor from "rich-markdown-editor";
|
||||
|
||||
const PartForm = (props) => {
|
||||
const onSubmit = (data) => {
|
||||
props.onSave(data, props?.part?.id)
|
||||
const { addMessage } = useFlash()
|
||||
const [description, setDescription] = useState(props?.part?.description)
|
||||
const onSubmit = async (data, e) => {
|
||||
|
||||
await props.onSave({
|
||||
...data,
|
||||
description,
|
||||
}, props?.part?.id)
|
||||
const shouldOpenIde = e?.nativeEvent?.submitter?.dataset?.openIde
|
||||
if(shouldOpenIde) {
|
||||
navigate(routes.partIde({id: props?.part?.id}))
|
||||
} else {
|
||||
navigate(routes.part({id: props?.part?.id}))
|
||||
}
|
||||
addMessage('Part updated.', { classes: 'rw-flash-success' })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-form-wrapper">
|
||||
<div className="max-w-7xl mx-auto mt-10">
|
||||
<Form onSubmit={onSubmit} error={props.error}>
|
||||
<FormError
|
||||
error={props.error}
|
||||
@@ -25,7 +43,7 @@ const PartForm = (props) => {
|
||||
|
||||
<Label
|
||||
name="title"
|
||||
className="rw-label"
|
||||
className="p-0"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Title
|
||||
@@ -39,41 +57,9 @@ const PartForm = (props) => {
|
||||
/>
|
||||
<FieldError name="title" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="description"
|
||||
className="rw-label"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Description
|
||||
</Label>
|
||||
<TextField
|
||||
name="description"
|
||||
defaultValue={props.part?.description}
|
||||
className="rw-input"
|
||||
errorClassName="rw-input rw-input-error"
|
||||
validation={{ required: true }}
|
||||
/>
|
||||
<FieldError name="description" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="code"
|
||||
className="rw-label"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Code
|
||||
</Label>
|
||||
<TextAreaField
|
||||
name="code"
|
||||
defaultValue={props.part?.code}
|
||||
className="rw-input"
|
||||
errorClassName="rw-input rw-input-error"
|
||||
validation={{ required: false }}
|
||||
/>
|
||||
<FieldError name="code" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="mainImage"
|
||||
className="rw-label"
|
||||
className="p-0"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Main image
|
||||
@@ -87,10 +73,27 @@ const PartForm = (props) => {
|
||||
/>
|
||||
<FieldError name="mainImage" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="description"
|
||||
className="p-0"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Description
|
||||
</Label>
|
||||
<div name="description" className="markdown-overrides bg-white p-12 my-10 min-h-md">
|
||||
<Editor
|
||||
defaultValue={props.part?.description}
|
||||
onChange={(valueFn) => setDescription(valueFn())}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="rw-button-group">
|
||||
<Submit disabled={props.loading} className="rw-button rw-button-blue">
|
||||
Save
|
||||
</Submit>
|
||||
<Submit disabled={props.loading} data-open-ide={true} className="rw-button rw-button-blue">
|
||||
Save and open IDE
|
||||
</Submit>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
|
||||
import avatar from 'src/assets/harold.jpg'
|
||||
|
||||
const DELETE_PART_MUTATION = gql`
|
||||
mutation DeletePartMutation($id: Int!) {
|
||||
deletePart(id: $id) {
|
||||
@@ -50,58 +52,27 @@ const PartsList = ({ parts }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-segment rw-table-wrapper-responsive">
|
||||
<table className="rw-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th>Code</th>
|
||||
<th>Main image</th>
|
||||
<th>Created at</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{parts.map((part) => (
|
||||
<tr key={part.id}>
|
||||
<td>{truncate(part.id)}</td>
|
||||
<td>{truncate(part.title)}</td>
|
||||
<td>{truncate(part.description)}</td>
|
||||
<td>{truncate(part.code)}</td>
|
||||
<td>{truncate(part.mainImage)}</td>
|
||||
<td>{timeTag(part.createdAt)}</td>
|
||||
<td>
|
||||
<nav className="rw-table-actions">
|
||||
<Link
|
||||
to={routes.part({ id: part.id })}
|
||||
title={'Show part ' + part.id + ' detail'}
|
||||
className="rw-button rw-button-small"
|
||||
>
|
||||
Show
|
||||
</Link>
|
||||
<Link
|
||||
to={routes.editPart({ id: part.id })}
|
||||
title={'Edit part ' + part.id}
|
||||
className="rw-button rw-button-small rw-button-blue"
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
<a
|
||||
href="#"
|
||||
title={'Delete part ' + part.id}
|
||||
className="rw-button rw-button-small rw-button-red"
|
||||
onClick={() => onDeleteClick(part.id)}
|
||||
>
|
||||
Delete
|
||||
</a>
|
||||
</nav>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="max-w-6xl mx-auto grid gap-8 grid-cols-4">
|
||||
{parts.map((part) => {
|
||||
return (
|
||||
<Link
|
||||
to={routes.part({ id: part.id })}
|
||||
title={'Show part ' + part.id + ' detail'}
|
||||
key={part.id}
|
||||
className="relative bg-gray-900 rounded-t-2xl"
|
||||
>
|
||||
<div className="rounded-t-2xl bg-gray-900">
|
||||
<div className="flex items-center p-2 text-indigo-200">
|
||||
<div className="h-full absolute inset-0 text-6xl flex items-center justify-center text-indigo-700" ><span>?</span></div>
|
||||
<div className="mr-4"><img src={avatar} className="rounded-full h-10 w-10" /></div>
|
||||
<h3>{part.title}</h3>
|
||||
</div>
|
||||
<div className="relative z-10">
|
||||
<img className="h-full" src={part.mainImage}/>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
103
web/src/components/User/User.js
Normal file
103
web/src/components/User/User.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { Link, routes, navigate } from '@redwoodjs/router'
|
||||
|
||||
const DELETE_USER_MUTATION = gql`
|
||||
mutation DeleteUserMutation($id: Int!) {
|
||||
deleteUser(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const jsonDisplay = (obj) => {
|
||||
return (
|
||||
<pre>
|
||||
<code>{JSON.stringify(obj, null, 2)}</code>
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
|
||||
const timeTag = (datetime) => {
|
||||
return (
|
||||
<time dateTime={datetime} title={datetime}>
|
||||
{new Date(datetime).toUTCString()}
|
||||
</time>
|
||||
)
|
||||
}
|
||||
|
||||
const checkboxInputTag = (checked) => {
|
||||
return <input type="checkbox" checked={checked} disabled />
|
||||
}
|
||||
|
||||
const User = ({ user }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [deleteUser] = useMutation(DELETE_USER_MUTATION, {
|
||||
onCompleted: () => {
|
||||
navigate(routes.users())
|
||||
addMessage('User deleted.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
|
||||
const onDeleteClick = (id) => {
|
||||
if (confirm('Are you sure you want to delete user ' + id + '?')) {
|
||||
deleteUser({ variables: { id } })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="rw-segment">
|
||||
<header className="rw-segment-header">
|
||||
<h2 className="rw-heading rw-heading-secondary">
|
||||
User {user.id} Detail
|
||||
</h2>
|
||||
</header>
|
||||
<table className="rw-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{user.id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>{user.email}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Created at</th>
|
||||
<td>{timeTag(user.createdAt)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Updated at</th>
|
||||
<td>{timeTag(user.updatedAt)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Image</th>
|
||||
<td>{user.image}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bio</th>
|
||||
<td>{user.bio}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<nav className="rw-button-group">
|
||||
<Link
|
||||
to={routes.editUser({ id: user.id })}
|
||||
className="rw-button rw-button-blue"
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
<a
|
||||
href="#"
|
||||
className="rw-button rw-button-red"
|
||||
onClick={() => onDeleteClick(user.id)}
|
||||
>
|
||||
Delete
|
||||
</a>
|
||||
</nav>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default User
|
||||
22
web/src/components/UserCell/UserCell.js
Normal file
22
web/src/components/UserCell/UserCell.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import User from 'src/components/User'
|
||||
|
||||
export const QUERY = gql`
|
||||
query FIND_USER_BY_ID($id: Int!) {
|
||||
user: user(id: $id) {
|
||||
id
|
||||
email
|
||||
createdAt
|
||||
updatedAt
|
||||
image
|
||||
bio
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => <div>User not found</div>
|
||||
|
||||
export const Success = ({ user }) => {
|
||||
return <User user={user} />
|
||||
}
|
||||
81
web/src/components/UserForm/UserForm.js
Normal file
81
web/src/components/UserForm/UserForm.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
Form,
|
||||
FormError,
|
||||
FieldError,
|
||||
Label,
|
||||
TextField,
|
||||
Submit,
|
||||
} from '@redwoodjs/forms'
|
||||
|
||||
const UserForm = (props) => {
|
||||
const onSubmit = (data) => {
|
||||
props.onSave(data, props?.user?.id)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-form-wrapper">
|
||||
<Form onSubmit={onSubmit} error={props.error}>
|
||||
<FormError
|
||||
error={props.error}
|
||||
wrapperClassName="rw-form-error-wrapper"
|
||||
titleClassName="rw-form-error-title"
|
||||
listClassName="rw-form-error-list"
|
||||
/>
|
||||
|
||||
<Label
|
||||
name="email"
|
||||
className="rw-label"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Email
|
||||
</Label>
|
||||
<TextField
|
||||
name="email"
|
||||
defaultValue={props.user?.email}
|
||||
className="rw-input"
|
||||
errorClassName="rw-input rw-input-error"
|
||||
validation={{ required: true }}
|
||||
/>
|
||||
<FieldError name="email" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="image"
|
||||
className="rw-label"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Image
|
||||
</Label>
|
||||
<TextField
|
||||
name="image"
|
||||
defaultValue={props.user?.image}
|
||||
className="rw-input"
|
||||
errorClassName="rw-input rw-input-error"
|
||||
/>
|
||||
<FieldError name="image" className="rw-field-error" />
|
||||
|
||||
<Label
|
||||
name="bio"
|
||||
className="rw-label"
|
||||
errorClassName="rw-label rw-label-error"
|
||||
>
|
||||
Bio
|
||||
</Label>
|
||||
<TextField
|
||||
name="bio"
|
||||
defaultValue={props.user?.bio}
|
||||
className="rw-input"
|
||||
errorClassName="rw-input rw-input-error"
|
||||
/>
|
||||
<FieldError name="bio" className="rw-field-error" />
|
||||
|
||||
<div className="rw-button-group">
|
||||
<Submit disabled={props.loading} className="rw-button rw-button-blue">
|
||||
Save
|
||||
</Submit>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default UserForm
|
||||
109
web/src/components/Users/Users.js
Normal file
109
web/src/components/Users/Users.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
|
||||
const DELETE_USER_MUTATION = gql`
|
||||
mutation DeleteUserMutation($id: Int!) {
|
||||
deleteUser(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const MAX_STRING_LENGTH = 150
|
||||
|
||||
const truncate = (text) => {
|
||||
let output = text
|
||||
if (text && text.length > MAX_STRING_LENGTH) {
|
||||
output = output.substring(0, MAX_STRING_LENGTH) + '...'
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
const jsonTruncate = (obj) => {
|
||||
return truncate(JSON.stringify(obj, null, 2))
|
||||
}
|
||||
|
||||
const timeTag = (datetime) => {
|
||||
return (
|
||||
<time dateTime={datetime} title={datetime}>
|
||||
{new Date(datetime).toUTCString()}
|
||||
</time>
|
||||
)
|
||||
}
|
||||
|
||||
const checkboxInputTag = (checked) => {
|
||||
return <input type="checkbox" checked={checked} disabled />
|
||||
}
|
||||
|
||||
const UsersList = ({ users }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [deleteUser] = useMutation(DELETE_USER_MUTATION, {
|
||||
onCompleted: () => {
|
||||
addMessage('User deleted.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
|
||||
const onDeleteClick = (id) => {
|
||||
if (confirm('Are you sure you want to delete user ' + id + '?')) {
|
||||
deleteUser({ variables: { id }, refetchQueries: ['USERS'] })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rw-segment rw-table-wrapper-responsive">
|
||||
<table className="rw-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Email</th>
|
||||
<th>Created at</th>
|
||||
<th>Updated at</th>
|
||||
<th>Image</th>
|
||||
<th>Bio</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td>{truncate(user.id)}</td>
|
||||
<td>{truncate(user.email)}</td>
|
||||
<td>{timeTag(user.createdAt)}</td>
|
||||
<td>{timeTag(user.updatedAt)}</td>
|
||||
<td>{truncate(user.image)}</td>
|
||||
<td>{truncate(user.bio)}</td>
|
||||
<td>
|
||||
<nav className="rw-table-actions">
|
||||
<Link
|
||||
to={routes.user({ id: user.id })}
|
||||
title={'Show user ' + user.id + ' detail'}
|
||||
className="rw-button rw-button-small"
|
||||
>
|
||||
Show
|
||||
</Link>
|
||||
<Link
|
||||
to={routes.editUser({ id: user.id })}
|
||||
title={'Edit user ' + user.id}
|
||||
className="rw-button rw-button-small rw-button-blue"
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
<a
|
||||
href="#"
|
||||
title={'Delete user ' + user.id}
|
||||
className="rw-button rw-button-small rw-button-red"
|
||||
onClick={() => onDeleteClick(user.id)}
|
||||
>
|
||||
Delete
|
||||
</a>
|
||||
</nav>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default UsersList
|
||||
33
web/src/components/UsersCell/UsersCell.js
Normal file
33
web/src/components/UsersCell/UsersCell.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
|
||||
import Users from 'src/components/Users'
|
||||
|
||||
export const QUERY = gql`
|
||||
query USERS {
|
||||
users {
|
||||
id
|
||||
email
|
||||
createdAt
|
||||
updatedAt
|
||||
image
|
||||
bio
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => {
|
||||
return (
|
||||
<div className="rw-text-center">
|
||||
{'No users yet. '}
|
||||
<Link to={routes.newUser()} className="rw-link">
|
||||
{'Create one?'}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Success = ({ users }) => {
|
||||
return <Users users={users} />
|
||||
}
|
||||
@@ -12,6 +12,30 @@
|
||||
* END --- TAILWIND GENERATOR EDIT
|
||||
*/
|
||||
|
||||
.markdown-overrides h4 {
|
||||
@apply text-lg font-bold;
|
||||
}
|
||||
.markdown-overrides h3 {
|
||||
@apply text-xl;
|
||||
}
|
||||
.markdown-overrides h2 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
.markdown-overrides h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
.markdown-overrides ol {
|
||||
@apply list-decimal;
|
||||
}
|
||||
.markdown-overrides ul {
|
||||
@apply list-disc;
|
||||
}
|
||||
|
||||
body {
|
||||
/* TODO can I use a tailwind class here? */
|
||||
background-color: #4a5568;
|
||||
}
|
||||
|
||||
button, input, label, textarea {
|
||||
display: block;
|
||||
outline: none;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import { useAuth } from '@redwoodjs/auth'
|
||||
import { Flash } from '@redwoodjs/web'
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
|
||||
import avatar from 'src/assets/harold.jpg'
|
||||
import Svg from 'src/components/Svg'
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
|
||||
const MainLayout = ({ children }) => {
|
||||
const { logIn, logOut, isAuthenticated } = useAuth()
|
||||
@@ -28,11 +30,21 @@ const MainLayout = ({ children }) => {
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="flex items-center">
|
||||
<li className="mr-8 rounded-full border-2 border-indigo-300"><Svg name="plus" className="text-indigo-300" /></li>
|
||||
<li className="mr-12 p-px border-2 rounded-full border-indigo-300"><img src={avatar} className="rounded-full h-10 w-10" /></li>
|
||||
<li className="mr-8 rounded-full border-2 border-indigo-300">
|
||||
<Link to={routes.newPart()}>
|
||||
<Svg name="plus" className="text-indigo-300" />
|
||||
</Link>
|
||||
</li>
|
||||
<li className="mr-12 p-px border-2 rounded-full border-indigo-300 text-indigo-200">
|
||||
<a href="#" onClick={isAuthenticated ? logOut : logIn}>
|
||||
{isAuthenticated ? 'Log Out' : 'Log In'}
|
||||
<img src={avatar} className="rounded-full h-10 w-10" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<Flash timeout={1000} />
|
||||
<main>{children}</main>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import { Flash } from '@redwoodjs/web'
|
||||
|
||||
|
||||
const PartsLayout = (props) => {
|
||||
return (
|
||||
<div className="rw-scaffold">
|
||||
<Flash timeout={1000} />
|
||||
<header className="rw-header">
|
||||
<h1 className="rw-heading rw-heading-primary">
|
||||
<Link to={routes.parts()} className="rw-link">
|
||||
Parts
|
||||
</Link>
|
||||
</h1>
|
||||
<Link to={routes.newPart()} className="rw-button rw-button-green">
|
||||
<div className="rw-button-icon">+</div> New Part
|
||||
</Link>
|
||||
</header>
|
||||
<main className="rw-main">{props.children}</main>
|
||||
<div className="mt-8">
|
||||
<main>{props.children}</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const PostsLayout = (props) => {
|
||||
<div className="rw-button-icon">+</div> New Post
|
||||
</Link>
|
||||
</header>
|
||||
<main className="rw-main">{props.children}</main>
|
||||
<main>{props.children}</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import PartsLayout from 'src/layouts/PartsLayout'
|
||||
import EditPartCell from 'src/components/EditPartCell'
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
|
||||
const EditPartPage = ({ id }) => {
|
||||
return (
|
||||
<PartsLayout>
|
||||
<MainLayout>
|
||||
<EditPartCell id={id} />
|
||||
</PartsLayout>
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
12
web/src/pages/EditUserPage/EditUserPage.js
Normal file
12
web/src/pages/EditUserPage/EditUserPage.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import EditUserCell from 'src/components/EditUserCell'
|
||||
|
||||
const EditUserPage = ({ id }) => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<EditUserCell id={id} />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditUserPage
|
||||
13
web/src/pages/IdePartPage/IdePartPage.js
Normal file
13
web/src/pages/IdePartPage/IdePartPage.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import IdePartCell from 'src/components/IdePartCell'
|
||||
|
||||
const IdePartPage = ({id}) => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<IdePartCell id={id} />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default IdePartPage
|
||||
7
web/src/pages/IdePartPage/IdePartPage.stories.js
Normal file
7
web/src/pages/IdePartPage/IdePartPage.stories.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import IdePartPage from './IdePartPage'
|
||||
|
||||
export const generated = () => {
|
||||
return <IdePartPage />
|
||||
}
|
||||
|
||||
export default { title: 'Pages/IdePartPage' }
|
||||
11
web/src/pages/IdePartPage/IdePartPage.test.js
Normal file
11
web/src/pages/IdePartPage/IdePartPage.test.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { render } from '@redwoodjs/testing'
|
||||
|
||||
import IdePartPage from './IdePartPage'
|
||||
|
||||
describe('IdePartPage', () => {
|
||||
it('renders successfully', () => {
|
||||
expect(() => {
|
||||
render(<IdePartPage />)
|
||||
}).not.toThrow()
|
||||
})
|
||||
})
|
||||
12
web/src/pages/NewUserPage/NewUserPage.js
Normal file
12
web/src/pages/NewUserPage/NewUserPage.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import NewUser from 'src/components/NewUser'
|
||||
|
||||
const NewUserPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<NewUser />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default NewUserPage
|
||||
12
web/src/pages/UserPage/UserPage.js
Normal file
12
web/src/pages/UserPage/UserPage.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import UserCell from 'src/components/UserCell'
|
||||
|
||||
const UserPage = ({ id }) => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<UserCell id={id} />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default UserPage
|
||||
12
web/src/pages/UsersPage/UsersPage.js
Normal file
12
web/src/pages/UsersPage/UsersPage.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import UsersCell from 'src/components/UsersCell'
|
||||
|
||||
const UsersPage = () => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<UsersCell />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default UsersPage
|
||||
@@ -7,7 +7,17 @@ module.exports = {
|
||||
},
|
||||
purge: [],
|
||||
theme: {
|
||||
extend: {}
|
||||
extend: {
|
||||
maxWidth: {
|
||||
'7xl': '80rem',
|
||||
'8xl': '96rem',
|
||||
'9xl': '110rem',
|
||||
},
|
||||
minHeight: {
|
||||
'md': '28rem'
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
variants: {},
|
||||
plugins: []
|
||||
|
||||
401
yarn.lock
401
yarn.lock
@@ -223,7 +223,16 @@
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.10.4":
|
||||
"@babel/generator@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468"
|
||||
integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.12.1"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3"
|
||||
integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==
|
||||
@@ -473,6 +482,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.0.tgz#a9d7e11aead25d3b422d17b2c6502c8dddef6a5d"
|
||||
integrity sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==
|
||||
|
||||
"@babel/parser@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.1.tgz#dc03f543a0ed51396d4081463df66ecb3a2efa53"
|
||||
integrity sha512-xjZsx0sBjb6J2+QkoHI69UeD2EWbsyUW0WyZKOoJ9sBrQLxfOApWEefR9dIVOYJVj97VRXnLKLDvnn3dPDNgww==
|
||||
|
||||
"@babel/plugin-proposal-async-generator-functions@^7.10.4":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558"
|
||||
@@ -1309,6 +1323,21 @@
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/traverse@^7.4.5":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e"
|
||||
integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.12.1"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.11.0"
|
||||
"@babel/parser" "^7.12.1"
|
||||
"@babel/types" "^7.12.1"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@7.11.5", "@babel/types@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
|
||||
@@ -1327,6 +1356,15 @@
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae"
|
||||
integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@bcoe/v8-coverage@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
@@ -1384,7 +1422,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
|
||||
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
|
||||
|
||||
"@emotion/is-prop-valid@0.8.8":
|
||||
"@emotion/is-prop-valid@0.8.8", "@emotion/is-prop-valid@^0.8.8":
|
||||
version "0.8.8"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||
@@ -1430,12 +1468,12 @@
|
||||
"@emotion/styled-base" "^10.0.27"
|
||||
babel-plugin-emotion "^10.0.27"
|
||||
|
||||
"@emotion/stylis@0.8.5":
|
||||
"@emotion/stylis@0.8.5", "@emotion/stylis@^0.8.4":
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
|
||||
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
|
||||
|
||||
"@emotion/unitless@0.7.5":
|
||||
"@emotion/unitless@0.7.5", "@emotion/unitless@^0.7.4":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||
@@ -3152,6 +3190,13 @@
|
||||
"@types/koa" "*"
|
||||
graphql "^14.5.3"
|
||||
|
||||
"@types/hast@^2.0.0":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9"
|
||||
integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==
|
||||
dependencies:
|
||||
"@types/unist" "*"
|
||||
|
||||
"@types/history@*":
|
||||
version "4.7.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.7.tgz#613957d900fab9ff84c8dfb24fa3eef0c2a40896"
|
||||
@@ -3440,6 +3485,11 @@
|
||||
dependencies:
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@types/unist@*":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
|
||||
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
|
||||
|
||||
"@types/webpack-env@^1.15.0":
|
||||
version "1.15.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a"
|
||||
@@ -4795,6 +4845,16 @@ babel-plugin-react-docgen@^4.0.0:
|
||||
react-docgen "^5.0.0"
|
||||
recast "^0.14.7"
|
||||
|
||||
"babel-plugin-styled-components@>= 1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.11.1.tgz#5296a9e557d736c3186be079fff27c6665d63d76"
|
||||
integrity sha512-YwrInHyKUk1PU3avIRdiLyCpM++18Rs1NgyMXEAQC33rIXs/vro0A+stf4sT0Gf22Got+xRWB8Cm0tw+qkRzBA==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.0.0"
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
babel-plugin-syntax-jsx "^6.18.0"
|
||||
lodash "^4.17.11"
|
||||
|
||||
babel-plugin-syntax-jsx@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||
@@ -5453,6 +5513,11 @@ camelcase@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e"
|
||||
integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==
|
||||
|
||||
camelize@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
||||
integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
|
||||
|
||||
can-use-dom@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a"
|
||||
@@ -5936,6 +6001,11 @@ compression@^1.7.4:
|
||||
safe-buffer "5.1.2"
|
||||
vary "~1.1.2"
|
||||
|
||||
compute-scroll-into-view@^1.0.16:
|
||||
version "1.0.16"
|
||||
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz#5b7bf4f7127ea2c19b750353d7ce6776a90ee088"
|
||||
integrity sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
@@ -6254,6 +6324,11 @@ crypto-random-string@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
|
||||
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
|
||||
|
||||
css-color-keywords@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||
integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
|
||||
|
||||
css-loader@^3.0.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645"
|
||||
@@ -6316,6 +6391,15 @@ css-select@^2.0.0:
|
||||
domutils "^1.7.0"
|
||||
nth-check "^1.0.2"
|
||||
|
||||
css-to-react-native@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
|
||||
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
|
||||
dependencies:
|
||||
camelize "^1.0.0"
|
||||
css-color-keywords "^1.0.0"
|
||||
postcss-value-parser "^4.0.2"
|
||||
|
||||
css-tree@1.0.0-alpha.37:
|
||||
version "1.0.0-alpha.37"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22"
|
||||
@@ -7063,7 +7147,7 @@ entities@^1.1.1, entities@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
entities@^2.0.0:
|
||||
entities@^2.0.0, entities@~2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
|
||||
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
|
||||
@@ -8675,6 +8759,17 @@ hastscript@^5.0.0:
|
||||
property-information "^5.0.0"
|
||||
space-separated-tokens "^1.0.0"
|
||||
|
||||
hastscript@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640"
|
||||
integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
comma-separated-tokens "^1.0.0"
|
||||
hast-util-parse-selector "^2.0.0"
|
||||
property-information "^5.0.0"
|
||||
space-separated-tokens "^1.0.0"
|
||||
|
||||
he@^1.1.0, he@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
@@ -8699,7 +8794,7 @@ hmac-drbg@^1.0.0:
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
@@ -10527,6 +10622,13 @@ lines-and-columns@^1.1.6:
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
|
||||
|
||||
linkify-it@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
|
||||
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
|
||||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
listr-silent-renderer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
|
||||
@@ -10899,6 +11001,22 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
markdown-it-container@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b"
|
||||
integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==
|
||||
|
||||
markdown-it@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
|
||||
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~2.0.0"
|
||||
linkify-it "^2.0.0"
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.5"
|
||||
|
||||
markdown-to-jsx@^6.11.4:
|
||||
version "6.11.4"
|
||||
resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz#b4528b1ab668aef7fe61c1535c27e837819392c5"
|
||||
@@ -10926,6 +11044,11 @@ mdn-data@2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978"
|
||||
integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==
|
||||
|
||||
mdurl@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@@ -11807,6 +11930,11 @@ optionator@^0.9.1:
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
orderedmap@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789"
|
||||
integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==
|
||||
|
||||
original@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
|
||||
@@ -11824,6 +11952,11 @@ os-tmpdir@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
outline-icons@^1.21.0-3:
|
||||
version "1.21.0-6"
|
||||
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.21.0-6.tgz#bbf63fe6cc88ca2fe391e6ba6cc8b62a948607e3"
|
||||
integrity sha512-iEVK2zTEZ3sLFLsko/V6z3AEiM2EAjEUyLIOzAT2cqRglIbaIWdyitotKVMb2hWZo66bSvHxA/Rdvv51sw5RhA==
|
||||
|
||||
p-each-series@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48"
|
||||
@@ -11995,6 +12128,18 @@ parse-entities@^1.1.2:
|
||||
is-decimal "^1.0.0"
|
||||
is-hexadecimal "^1.0.0"
|
||||
|
||||
parse-entities@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
|
||||
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
|
||||
dependencies:
|
||||
character-entities "^1.0.0"
|
||||
character-entities-legacy "^1.0.0"
|
||||
character-reference-invalid "^1.0.0"
|
||||
is-alphanumerical "^1.0.0"
|
||||
is-decimal "^1.0.0"
|
||||
is-hexadecimal "^1.0.0"
|
||||
|
||||
parse-json@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
|
||||
@@ -12364,7 +12509,7 @@ postcss-value-parser@^3.3.0:
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
||||
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
|
||||
|
||||
postcss-value-parser@^4.1.0:
|
||||
postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
|
||||
@@ -12476,6 +12621,13 @@ prettysize@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/prettysize/-/prettysize-2.0.0.tgz#902c02480d865d9cc0813011c9feb4fa02ce6996"
|
||||
integrity sha512-VVtxR7sOh0VsG8o06Ttq5TrI1aiZKmC+ClSn4eBPaNf4SHr5lzbYW+kYGX3HocBL/MfpVrRfFZ9V3vCbLaiplg==
|
||||
|
||||
prismjs@^1.19.0, prismjs@~1.22.0:
|
||||
version "1.22.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.22.0.tgz#73c3400afc58a823dd7eed023f8e1ce9fd8977fa"
|
||||
integrity sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w==
|
||||
optionalDependencies:
|
||||
clipboard "^2.0.0"
|
||||
|
||||
prismjs@^1.8.4:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03"
|
||||
@@ -12550,7 +12702,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.4"
|
||||
|
||||
prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
@@ -12571,6 +12723,129 @@ proptypes@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/proptypes/-/proptypes-1.1.0.tgz#78b3828a5aa6bb1308939e0de3c6044dfd4bd239"
|
||||
integrity sha1-eLOCilqmuxMIk54N48YETf1L0jk=
|
||||
|
||||
prosemirror-commands@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.4.tgz#991563e67623acab4f8c510fad1570f8b4693780"
|
||||
integrity sha512-kj4Qi+8h3EpJtZuuEDwZ9h2/QNGWDsIX/CzjmClxi9GhxWyBUMVUvIFk0mgdqHyX20lLeGmOpc0TLA5aPzgpWg==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
|
||||
prosemirror-dropcursor@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.2.tgz#28738c4ed7102e814d7a8a26d70018523fc7cd6d"
|
||||
integrity sha512-4c94OUGyobGnwcQI70OXyMhE/9T4aTgjU+CHxkd5c7D+jH/J0mKM/lk+jneFVKt7+E4/M0D9HzRPifu8U28Thw==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.1.0"
|
||||
prosemirror-view "^1.1.0"
|
||||
|
||||
prosemirror-gapcursor@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.5.tgz#0c37fd6cbb1d7c46358c2e7397f8da9a8b5c6246"
|
||||
integrity sha512-SjbUZq5pgsBDuV3hu8GqgIpZR5eZvGLM+gPQTqjVVYSMUCfKW3EGXTEYaLHEl1bGduwqNC95O3bZflgtAb4L6w==
|
||||
dependencies:
|
||||
prosemirror-keymap "^1.0.0"
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-view "^1.0.0"
|
||||
|
||||
prosemirror-history@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.1.3.tgz#4f76a1e71db4ef7cdf0e13dec6d8da2aeaecd489"
|
||||
integrity sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==
|
||||
dependencies:
|
||||
prosemirror-state "^1.2.2"
|
||||
prosemirror-transform "^1.0.0"
|
||||
rope-sequence "^1.3.0"
|
||||
|
||||
prosemirror-inputrules@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638"
|
||||
integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
|
||||
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz#8b481bf8389a5ac40d38dbd67ec3da2c7eac6a6d"
|
||||
integrity sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
w3c-keyname "^2.2.0"
|
||||
|
||||
prosemirror-markdown@^1.4.4:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.5.0.tgz#1c0129640c33e23217fbf80ebb24486a40a759c1"
|
||||
integrity sha512-ugTyZfTu1l2E3EI6+DwD917mz2Sk5E4R01Nh67yMffGg4S9ZetC81g1VIKGCaak4jnoP4BMUIOUJyXAS6xFLaA==
|
||||
dependencies:
|
||||
markdown-it "^10.0.0"
|
||||
prosemirror-model "^1.0.0"
|
||||
|
||||
prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.11.2, prosemirror-model@^1.8.1:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.12.0.tgz#deb6acbce5c62ea35ef3d59c7d4c54f65d6d9fba"
|
||||
integrity sha512-B5syrXluQwEPfih8PqZcVg2VWRUf8Rj97K/VNSkQtjUPL1BCoTUgdLERIlxdWHkwqvujFsT3Pw5ubc4/ofF1jQ==
|
||||
dependencies:
|
||||
orderedmap "^1.1.0"
|
||||
|
||||
prosemirror-schema-list@^1.1.2:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.4.tgz#471f9caf2d2bed93641d2e490434c0d2d4330df1"
|
||||
integrity sha512-pNTuZflacFOBlxrTcWSdWhjoB8BaucwfJVp/gJNxztOwaN3wQiC65axclXyplf6TKgXD/EkWfS/QAov3/Znadw==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
|
||||
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.3.tgz#b2862866b14dec2b3ae1ab18229f2bd337651a2c"
|
||||
integrity sha512-PLXh2VJsIgvlgSTH6I2Yg6vk1CzPDp21DFreVpQtDMY2S6WaMmrQgDTLRcsrD8X38v8Yc873H7+ogdGzyIPn+w==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
|
||||
prosemirror-tables@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.1.1.tgz#ad66300cc49500455cf1243bb129c9e7d883321e"
|
||||
integrity sha512-LmCz4jrlqQZRsYRDzCRYf/pQ5CUcSOyqZlAj5kv67ZWBH1SVLP2U9WJEvQfimWgeRlIz0y0PQVqO1arRm1+woA==
|
||||
dependencies:
|
||||
prosemirror-keymap "^1.1.2"
|
||||
prosemirror-model "^1.8.1"
|
||||
prosemirror-state "^1.3.1"
|
||||
prosemirror-transform "^1.2.1"
|
||||
prosemirror-view "^1.13.3"
|
||||
|
||||
prosemirror-transform@1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.2.5.tgz#7a3e2c61fcdbaf1d0844a2a3bc34fc3524e9809c"
|
||||
integrity sha512-eqeIaxWtUfOnpA1ERrXCuSIMzqIJtL9Qrs5uJMCjY5RMSaH5o4pc390SAjn/IDPeIlw6auh0hCCXs3wRvGnQug==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
|
||||
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.2.8.tgz#4b86544fa43637fe381549fb7b019f4fb71fe65c"
|
||||
integrity sha512-hKqceqv9ZmMQXNQkhFjr0KFGPvkhygaWND+uIM0GxRpALrKfxP97SsgHTBs3OpJhDmh5N+mB4D/CksB291Eavg==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
|
||||
prosemirror-utils@^0.9.6:
|
||||
version "0.9.6"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-utils/-/prosemirror-utils-0.9.6.tgz#3d97bd85897e3b535555867dc95a51399116a973"
|
||||
integrity sha512-UC+j9hQQ1POYfMc5p7UFxBTptRiGPR7Kkmbl3jVvU8VgQbkI89tR/GK+3QYC8n+VvBZrtAoCrJItNhWSxX3slA==
|
||||
|
||||
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.15.7:
|
||||
version "1.16.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.16.0.tgz#024440a8e9acbbb5826572eef58c21c11cd1e454"
|
||||
integrity sha512-iFtStCw2byF0yLc3mm1ezGdFSd6SWM4pnJod+ZaJiU5ju36QdYM4Xwa+qNm/AaI2/MgxpJqi8jsGWOJNkeBQ/Q==
|
||||
dependencies:
|
||||
prosemirror-model "^1.1.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.1.0"
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
|
||||
@@ -12876,6 +13151,11 @@ react-lifecycles-compat@^3.0.4:
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-medium-image-zoom@^3.0.16:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/react-medium-image-zoom/-/react-medium-image-zoom-3.1.2.tgz#5ac4441f1d424bd9680a25bfc2591be3d7704a42"
|
||||
integrity sha512-werjufn5o4ytdyvJNzfqXCilovDhMyREH0qeJhCjV5brNAyfV7anZmvpFc3FApbuVXwBkzHMuQkV2z/GyEQatg==
|
||||
|
||||
react-popper-tooltip@^2.8.3:
|
||||
version "2.11.1"
|
||||
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz#3c4bdfd8bc10d1c2b9a162e859bab8958f5b2644"
|
||||
@@ -12897,6 +13177,13 @@ react-popper@^1.3.7:
|
||||
typed-styles "^0.0.7"
|
||||
warning "^4.0.2"
|
||||
|
||||
react-portal@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-4.2.1.tgz#12c1599238c06fb08a9800f3070bea2a3f78b1a6"
|
||||
integrity sha512-fE9kOBagwmTXZ3YGRYb4gcMy+kSA+yLO0xnPankjRlfBv4uCpFXqKPfkpsGQQR15wkZ9EssnvTOl1yMzbkxhPQ==
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-sizeme@^2.6.7:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-2.6.12.tgz#ed207be5476f4a85bf364e92042520499455453e"
|
||||
@@ -13077,6 +13364,15 @@ refractor@^2.4.1:
|
||||
parse-entities "^1.1.2"
|
||||
prismjs "~1.17.0"
|
||||
|
||||
refractor@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.2.0.tgz#bc46f7cfbb6adbf45cd304e8e299b7fa854804e0"
|
||||
integrity sha512-hSo+EyMIZTLBvNNgIU5lW4yjCzNYMZ4dcEhBq/3nReGfqzd2JfVhdlPDfU9rEsgcAyWx+OimIIUoL4ZU7NtYHQ==
|
||||
dependencies:
|
||||
hastscript "^6.0.0"
|
||||
parse-entities "^2.0.0"
|
||||
prismjs "~1.22.0"
|
||||
|
||||
regenerate-unicode-properties@^8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
|
||||
@@ -13371,6 +13667,38 @@ reusify@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rich-markdown-editor@^11.0.2:
|
||||
version "11.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rich-markdown-editor/-/rich-markdown-editor-11.0.2.tgz#281bca9670a30f6b528ace71a4ee06a24210a464"
|
||||
integrity sha512-b9WigUymZA8BucrduIngBB+jrDuCHjwBdKa4aP6aehS5JQqKnTY++sjiHOvaFDnD75GJGUw/4wsNt76KdYAyCw==
|
||||
dependencies:
|
||||
copy-to-clipboard "^3.0.8"
|
||||
lodash "^4.17.11"
|
||||
markdown-it-container "^3.0.0"
|
||||
outline-icons "^1.21.0-3"
|
||||
prismjs "^1.19.0"
|
||||
prosemirror-commands "^1.1.4"
|
||||
prosemirror-dropcursor "^1.3.2"
|
||||
prosemirror-gapcursor "^1.1.5"
|
||||
prosemirror-history "^1.1.3"
|
||||
prosemirror-inputrules "^1.1.3"
|
||||
prosemirror-keymap "^1.1.4"
|
||||
prosemirror-markdown "^1.4.4"
|
||||
prosemirror-model "^1.11.2"
|
||||
prosemirror-schema-list "^1.1.2"
|
||||
prosemirror-state "^1.3.3"
|
||||
prosemirror-tables "^1.1.1"
|
||||
prosemirror-transform "1.2.5"
|
||||
prosemirror-utils "^0.9.6"
|
||||
prosemirror-view "^1.15.7"
|
||||
react-medium-image-zoom "^3.0.16"
|
||||
react-portal "^4.2.1"
|
||||
refractor "^3.1.0"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
slugify "^1.4.0"
|
||||
smooth-scroll-into-view-if-needed "^1.1.27"
|
||||
typescript "3.7.5"
|
||||
|
||||
rimraf@2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
@@ -13400,6 +13728,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rope-sequence@^1.3.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b"
|
||||
integrity sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg==
|
||||
|
||||
rsvp@^4.8.4:
|
||||
version "4.8.5"
|
||||
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
|
||||
@@ -13523,6 +13856,13 @@ schema-utils@^2.7.1:
|
||||
ajv "^6.12.4"
|
||||
ajv-keywords "^3.5.2"
|
||||
|
||||
scroll-into-view-if-needed@^2.2.26:
|
||||
version "2.2.26"
|
||||
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.26.tgz#e4917da0c820135ff65ad6f7e4b7d7af568c4f13"
|
||||
integrity sha512-SQ6AOKfABaSchokAmmaxVnL9IArxEnLEX9j4wAZw+x4iUTb40q7irtHG3z4GtAWz5veVZcCnubXDBRyLVQaohw==
|
||||
dependencies:
|
||||
compute-scroll-into-view "^1.0.16"
|
||||
|
||||
select-hose@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
@@ -13838,6 +14178,18 @@ slice-ansi@^3.0.0:
|
||||
astral-regex "^2.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
|
||||
slugify@^1.4.0:
|
||||
version "1.4.5"
|
||||
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.5.tgz#a7517acf5f4c02a4df41e735354b660a4ed1efcf"
|
||||
integrity sha512-WpECLAgYaxHoEAJ8Q1Lo8HOs1ngn7LN7QjXgOLbmmfkcWvosyk4ZTXkTzKyhngK640USTZUlgoQJfED1kz5fnQ==
|
||||
|
||||
smooth-scroll-into-view-if-needed@^1.1.27:
|
||||
version "1.1.29"
|
||||
resolved "https://registry.yarnpkg.com/smooth-scroll-into-view-if-needed/-/smooth-scroll-into-view-if-needed-1.1.29.tgz#4f532d9f0353dbca122e546fb062e7b5e0643734"
|
||||
integrity sha512-UxvIEbmMEqwbw0aZI4SOAtwwkMaLYVION20bDQmazVp3sNb1+WIA5koukqoJizRuAAUANRmcBcrTnodcB7maqw==
|
||||
dependencies:
|
||||
scroll-into-view-if-needed "^2.2.26"
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
@@ -14312,6 +14664,22 @@ style-loader@^1.0.0, style-loader@^1.1.3:
|
||||
loader-utils "^2.0.0"
|
||||
schema-utils "^2.6.6"
|
||||
|
||||
styled-components@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.0.tgz#6dcb5aa8a629c84b8d5ab34b7167e3e0c6f7ed74"
|
||||
integrity sha512-9qE8Vgp8C5cpGAIdFaQVAl89Zgx1TDM4Yf4tlHbO9cPijtpSXTMLHy9lmP0lb+yImhgPFb1AmZ1qMUubmg3HLg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@babel/traverse" "^7.4.5"
|
||||
"@emotion/is-prop-valid" "^0.8.8"
|
||||
"@emotion/stylis" "^0.8.4"
|
||||
"@emotion/unitless" "^0.7.4"
|
||||
babel-plugin-styled-components ">= 1"
|
||||
css-to-react-native "^3.0.0"
|
||||
hoist-non-react-statics "^3.0.0"
|
||||
shallowequal "^1.1.0"
|
||||
supports-color "^5.5.0"
|
||||
|
||||
subscriptions-transport-ws@0.9.18:
|
||||
version "0.9.18"
|
||||
resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97"
|
||||
@@ -14339,7 +14707,7 @@ supports-color@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||
|
||||
supports-color@^5.3.0, supports-color@^5.4.0:
|
||||
supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
@@ -14939,6 +15307,11 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@3.7.5:
|
||||
version "3.7.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
|
||||
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
|
||||
|
||||
typescript@^4.0.2, typescript@~4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
|
||||
@@ -14949,6 +15322,11 @@ ua-parser-js@^0.7.18:
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
|
||||
integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
|
||||
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
|
||||
|
||||
unc-path-regex@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
|
||||
@@ -15298,6 +15676,11 @@ w3c-hr-time@^1.0.2:
|
||||
dependencies:
|
||||
browser-process-hrtime "^1.0.0"
|
||||
|
||||
w3c-keyname@^2.2.0:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
|
||||
integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
|
||||
|
||||
w3c-xmlserializer@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
|
||||
|
||||
Reference in New Issue
Block a user