Merge pull request #1 from Irev-Dev/experiment-with-cascade-studio
Experiment with cascade studio
This commit was merged in pull request #1.
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "web/src/cascade"]
|
||||||
|
path = web/src/cascade
|
||||||
|
url = https://github.com/zalo/CascadeStudio.git
|
||||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -7,5 +7,13 @@
|
|||||||
},
|
},
|
||||||
"[prisma]": {
|
"[prisma]": {
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
}
|
},
|
||||||
|
"eslint.workingDirectories": [
|
||||||
|
"./api",
|
||||||
|
"./web/src/components",
|
||||||
|
"./web/src/layouts",
|
||||||
|
"./web/src/pages",
|
||||||
|
"./web/src/index.js",
|
||||||
|
"./web/src/Routes.js",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
52
api/prisma/migrations/20201011043647-create-parts/README.md
Normal file
52
api/prisma/migrations/20201011043647-create-parts/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Migration `20201011043647-create-parts`
|
||||||
|
|
||||||
|
This migration has been generated by Kurt Hutten at 10/11/2020, 3:36:47 PM.
|
||||||
|
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||||
|
|
||||||
|
## Database Steps
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE "Part" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"mainImage" TEXT NOT NULL,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git schema.prisma schema.prisma
|
||||||
|
migration 20201009213512-create-posts..20201011043647-create-parts
|
||||||
|
--- datamodel.dml
|
||||||
|
+++ datamodel.dml
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
- url = "***"
|
||||||
|
+ url = "***"
|
||||||
|
}
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
@@ -15,4 +15,14 @@
|
||||||
|
title String
|
||||||
|
body String
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+model Part {
|
||||||
|
+ id Int @id @default(autoincrement())
|
||||||
|
+ title String
|
||||||
|
+ description String // markdown string
|
||||||
|
+ mainImage String // link to cloudinary
|
||||||
|
+ createdAt DateTime @default(now())
|
||||||
|
+ // userId
|
||||||
|
+ //likes, comments, reactions
|
||||||
|
+}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
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
|
||||||
|
mainImage String // link to cloudinary
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
// userId
|
||||||
|
//likes, comments, reactions
|
||||||
|
}
|
||||||
105
api/prisma/migrations/20201011043647-create-parts/steps.json
Normal file
105
api/prisma/migrations/20201011043647-create-parts/steps.json
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"version": "0.3.14-fixed",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"tag": "CreateModel",
|
||||||
|
"model": "Part"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "id",
|
||||||
|
"type": "Int",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"value": "autoincrement()"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "title",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "description",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "mainImage",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "createdAt",
|
||||||
|
"type": "DateTime",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "createdAt"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "createdAt"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"value": "now()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Migration `20201011052155-add-code-to-part`
|
||||||
|
|
||||||
|
This migration has been generated by Kurt Hutten at 10/11/2020, 4:21:55 PM.
|
||||||
|
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||||
|
|
||||||
|
## Database Steps
|
||||||
|
|
||||||
|
```sql
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Part" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"code" TEXT NOT NULL DEFAULT '// Welcome to Cascade Studio! Here are some useful functions:
|
||||||
|
// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()
|
||||||
|
// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()
|
||||||
|
// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),
|
||||||
|
// FilletEdges(), ChamferEdges(),
|
||||||
|
// Slider(), Button(), Checkbox()
|
||||||
|
let holeRadius = Slider("Radius", 30 , 20 , 40);
|
||||||
|
let sphere = Sphere(50);
|
||||||
|
let cylinderZ = Cylinder(holeRadius, 200, true);/nlet cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));
|
||||||
|
let cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));/nTranslate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));
|
||||||
|
|
||||||
|
Translate([-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" TEXT NOT NULL,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Part" ("id", "title", "description", "mainImage", "createdAt") SELECT "id", "title", "description", "mainImage", "createdAt" FROM "Part";
|
||||||
|
DROP TABLE "Part";
|
||||||
|
ALTER TABLE "new_Part" RENAME TO "Part";
|
||||||
|
PRAGMA foreign_key_check;
|
||||||
|
PRAGMA foreign_keys=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git schema.prisma schema.prisma
|
||||||
|
migration 20201011043647-create-parts..20201011052155-add-code-to-part
|
||||||
|
--- datamodel.dml
|
||||||
|
+++ datamodel.dml
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
- url = "***"
|
||||||
|
+ url = "***"
|
||||||
|
}
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
@@ -20,8 +20,9 @@
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"version": "0.3.14-fixed",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "code",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "code"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "code"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"value": "\"// 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!\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Migration `20201011082558-add-code-not-needed-upon-create`
|
||||||
|
|
||||||
|
This migration has been generated by Kurt Hutten at 10/11/2020, 7:25:58 PM.
|
||||||
|
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||||
|
|
||||||
|
## Database Steps
|
||||||
|
|
||||||
|
```sql
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Part" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"code" TEXT NOT NULL DEFAULT '// Welcome to Cascade Studio! Here are some useful functions:
|
||||||
|
// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()
|
||||||
|
// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()
|
||||||
|
// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),
|
||||||
|
// FilletEdges(), ChamferEdges(),
|
||||||
|
// Slider(), Button(), Checkbox()
|
||||||
|
let holeRadius = Slider("Radius", 30 , 20 , 40);
|
||||||
|
let sphere = Sphere(50);
|
||||||
|
let cylinderZ = Cylinder(holeRadius, 200, true);
|
||||||
|
let cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));
|
||||||
|
let cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));
|
||||||
|
Translate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));
|
||||||
|
|
||||||
|
Translate([-25, 0, 40], Text3D("Hi!"));
|
||||||
|
// Don''t forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!',
|
||||||
|
"mainImage" TEXT NOT NULL,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Part" ("id", "title", "description", "mainImage", "createdAt", "code") SELECT "id", "title", "description", "mainImage", "createdAt", "code" FROM "Part";
|
||||||
|
DROP TABLE "Part";
|
||||||
|
ALTER TABLE "new_Part" RENAME TO "Part";
|
||||||
|
PRAGMA foreign_key_check;
|
||||||
|
PRAGMA foreign_keys=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git schema.prisma schema.prisma
|
||||||
|
migration 20201011052155-add-code-to-part..20201011082558-add-code-not-needed-upon-create
|
||||||
|
--- datamodel.dml
|
||||||
|
+++ datamodel.dml
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
- url = "***"
|
||||||
|
+ url = "***"
|
||||||
|
}
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
@@ -20,9 +20,9 @@
|
||||||
|
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!")
|
||||||
|
+ 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
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"version": "0.3.14-fixed",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"tag": "UpdateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Part",
|
||||||
|
"field": "code"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"newValue": "\"// 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!\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Migration `20201011095227-create-contact`
|
||||||
|
|
||||||
|
This migration has been generated by Kurt Hutten at 10/11/2020, 8:52:27 PM.
|
||||||
|
You can check out the [state of the schema](./schema.prisma) after the migration.
|
||||||
|
|
||||||
|
## Database Steps
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE "Contact" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"email" TEXT NOT NULL,
|
||||||
|
"message" TEXT NOT NULL,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git schema.prisma schema.prisma
|
||||||
|
migration 20201011082558-add-code-not-needed-upon-create..20201011095227-create-contact
|
||||||
|
--- datamodel.dml
|
||||||
|
+++ datamodel.dml
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
- url = "***"
|
||||||
|
+ url = "***"
|
||||||
|
}
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
@@ -26,4 +26,12 @@
|
||||||
|
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())
|
||||||
|
+}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
datasource DS {
|
||||||
|
// optionally set multiple providers
|
||||||
|
// example: provider = ["sqlite", "postgresql"]
|
||||||
|
provider = "sqlite"
|
||||||
|
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())
|
||||||
|
}
|
||||||
105
api/prisma/migrations/20201011095227-create-contact/steps.json
Normal file
105
api/prisma/migrations/20201011095227-create-contact/steps.json
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"version": "0.3.14-fixed",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"tag": "CreateModel",
|
||||||
|
"model": "Contact"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "id",
|
||||||
|
"type": "Int",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "id"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"value": "autoincrement()"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "name",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "email",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "message",
|
||||||
|
"type": "String",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateField",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "createdAt",
|
||||||
|
"type": "DateTime",
|
||||||
|
"arity": "Required"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateDirective",
|
||||||
|
"location": {
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "createdAt"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "CreateArgument",
|
||||||
|
"location": {
|
||||||
|
"tag": "Directive",
|
||||||
|
"path": {
|
||||||
|
"tag": "Field",
|
||||||
|
"model": "Contact",
|
||||||
|
"field": "createdAt"
|
||||||
|
},
|
||||||
|
"directive": "default"
|
||||||
|
},
|
||||||
|
"argument": "",
|
||||||
|
"value": "now()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
# Prisma Migrate lockfile v1
|
# Prisma Migrate lockfile v1
|
||||||
|
|
||||||
20201009213512-create-posts
|
20201009213512-create-posts
|
||||||
|
20201011043647-create-parts
|
||||||
|
20201011052155-add-code-to-part
|
||||||
|
20201011082558-add-code-not-needed-upon-create
|
||||||
|
20201011095227-create-contact
|
||||||
@@ -16,3 +16,22 @@ model Post {
|
|||||||
body String
|
body String
|
||||||
createdAt DateTime @default(now())
|
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())
|
||||||
|
}
|
||||||
|
|||||||
29
api/src/graphql/contacts.sdl.js
Normal file
29
api/src/graphql/contacts.sdl.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
export const schema = gql`
|
||||||
|
type Contact {
|
||||||
|
id: Int!
|
||||||
|
name: String!
|
||||||
|
email: String!
|
||||||
|
message: String!
|
||||||
|
createdAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query {
|
||||||
|
contacts: [Contact!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input CreateContactInput {
|
||||||
|
name: String!
|
||||||
|
email: String!
|
||||||
|
message: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input UpdateContactInput {
|
||||||
|
name: String
|
||||||
|
email: String
|
||||||
|
message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
createContact(input: CreateContactInput!): Contact
|
||||||
|
}
|
||||||
|
`
|
||||||
35
api/src/graphql/parts.sdl.js
Normal file
35
api/src/graphql/parts.sdl.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
export const schema = gql`
|
||||||
|
type Part {
|
||||||
|
id: Int!
|
||||||
|
title: String!
|
||||||
|
description: String!
|
||||||
|
code: String!
|
||||||
|
mainImage: String!
|
||||||
|
createdAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query {
|
||||||
|
parts: [Part!]!
|
||||||
|
part(id: Int!): Part
|
||||||
|
}
|
||||||
|
|
||||||
|
input CreatePartInput {
|
||||||
|
title: String!
|
||||||
|
description: String!
|
||||||
|
code: String
|
||||||
|
mainImage: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input UpdatePartInput {
|
||||||
|
title: String
|
||||||
|
description: String
|
||||||
|
code: String
|
||||||
|
mainImage: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
createPart(input: CreatePartInput!): Part!
|
||||||
|
updatePart(id: Int!, input: UpdatePartInput!): Part!
|
||||||
|
deletePart(id: Int!): Part!
|
||||||
|
}
|
||||||
|
`
|
||||||
24
api/src/services/contacts/contacts.js
Normal file
24
api/src/services/contacts/contacts.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { UserInputError } from '@redwoodjs/api'
|
||||||
|
|
||||||
|
import { db } from 'src/lib/db'
|
||||||
|
|
||||||
|
|
||||||
|
const validate = (input) => {
|
||||||
|
if (input.email && !input.email.match(/[^@]+@[^.]+\..+/)) {
|
||||||
|
throw new UserInputError("Can't create new contact", {
|
||||||
|
messages: {
|
||||||
|
email: ['is not formatted like an email address'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const contacts = () => {
|
||||||
|
return db.contact.findMany()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createContact = ({ input }) => {
|
||||||
|
|
||||||
|
validate(input)
|
||||||
|
return db.contact.create({ data: input })
|
||||||
|
}
|
||||||
9
api/src/services/contacts/contacts.test.js
Normal file
9
api/src/services/contacts/contacts.test.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
import { contacts } from './contacts'
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('contacts', () => {
|
||||||
|
it('returns true', () => {
|
||||||
|
expect(true).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
30
api/src/services/parts/parts.js
Normal file
30
api/src/services/parts/parts.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { db } from 'src/lib/db'
|
||||||
|
|
||||||
|
export const parts = () => {
|
||||||
|
return db.part.findMany()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const part = ({ id }) => {
|
||||||
|
return db.part.findOne({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createPart = ({ input }) => {
|
||||||
|
return db.part.create({
|
||||||
|
data: input,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updatePart = ({ id, input }) => {
|
||||||
|
return db.part.update({
|
||||||
|
data: input,
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deletePart = ({ id }) => {
|
||||||
|
return db.part.delete({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
9
api/src/services/parts/parts.test.js
Normal file
9
api/src/services/parts/parts.test.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
import { parts } from './parts'
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('parts', () => {
|
||||||
|
it('returns true', () => {
|
||||||
|
expect(true).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
12
netlify.toml
Normal file
12
netlify.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[build]
|
||||||
|
command = "yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up"
|
||||||
|
publish = "web/dist"
|
||||||
|
functions = "api/dist/functions"
|
||||||
|
|
||||||
|
[dev]
|
||||||
|
command = "yarn rw dev"
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from = "/*"
|
||||||
|
to = "/index.html"
|
||||||
|
status = 200
|
||||||
14
package.json
14
package.json
@@ -6,11 +6,23 @@
|
|||||||
"web"
|
"web"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"scripts": {
|
||||||
|
"comment": "Rather crude approach to move ts definitions into the public folder so the browser can grab them later in CascadeMain.js",
|
||||||
|
"move-ts-defs": "cp ./node_modules/opencascade.js/dist/opencascade.d.ts ./web/public && cp ./node_modules/three/src/Three.d.ts ./web/public && cp ./web/src/cascade/js/StandardLibraryIntellisense.ts ./web/public"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redwoodjs/core": "^0.19.2"
|
"@redwoodjs/core": "^0.19.2"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@redwoodjs/eslint-config"
|
"extends": "@redwoodjs/eslint-config",
|
||||||
|
"workingDirectories": [
|
||||||
|
"./api",
|
||||||
|
"./web/src/components",
|
||||||
|
"./web/src/layouts",
|
||||||
|
"./web/src/pages",
|
||||||
|
"./web/src/index.js",
|
||||||
|
"./web/src/Routes.js"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12",
|
"node": ">=12",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
[web]
|
[web]
|
||||||
port = 8910
|
port = 8910
|
||||||
apiProxyPath = "/.redwood/functions"
|
apiProxyPath = "/.netlify/functions"
|
||||||
[api]
|
[api]
|
||||||
port = 8911
|
port = 8911
|
||||||
[browser]
|
[browser]
|
||||||
|
|||||||
7
web/config/webpack.config.js
Normal file
7
web/config/webpack.config.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
new MonacoWebpackPlugin()
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -16,8 +16,15 @@
|
|||||||
"@redwoodjs/forms": "^0.19.2",
|
"@redwoodjs/forms": "^0.19.2",
|
||||||
"@redwoodjs/router": "^0.19.2",
|
"@redwoodjs/router": "^0.19.2",
|
||||||
"@redwoodjs/web": "^0.19.2",
|
"@redwoodjs/web": "^0.19.2",
|
||||||
|
"controlkit": "^0.1.9",
|
||||||
|
"golden-layout": "^1.5.9",
|
||||||
|
"jquery": "^3.5.1",
|
||||||
|
"monaco-editor": "^0.20.0",
|
||||||
|
"monaco-editor-webpack-plugin": "^1.9.1",
|
||||||
|
"opencascade.js": "^0.1.15",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1"
|
"react-dom": "^16.13.1",
|
||||||
|
"three": "^0.118.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
213
web/public/StandardLibraryIntellisense.ts
Normal file
213
web/public/StandardLibraryIntellisense.ts
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/** The list that stores all of the OpenCascade shapes for rendering.
|
||||||
|
* Add to this when using imported files or doing custom oc. operations.
|
||||||
|
* @example```sceneShapes.push(externalShapes['myStep.step']);``` */
|
||||||
|
var sceneShapes: oc.TopoDS_Shape[];
|
||||||
|
|
||||||
|
/** The dictionary that stores all of your imported STEP and IGES files. Push to sceneShapes to render in the view!
|
||||||
|
* @example```sceneShapes.push(externalShapes['myStep.step']);``` */
|
||||||
|
var externalShapes: { [filename: string]: oc.TopoDS_Shape };
|
||||||
|
|
||||||
|
/** Starts sketching a 2D shape which can contain lines, arcs, bezier splines, and fillets.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let sketch = new Sketch([0,0]).LineTo([100,0]).Fillet(20).LineTo([100,100]).End(true).Face();```*/
|
||||||
|
class Sketch {
|
||||||
|
constructor(startingPoint: number[]);
|
||||||
|
|
||||||
|
faces : oc.TopoDS_Face[];
|
||||||
|
wires : oc.TopoDS_Wire[];
|
||||||
|
firstPoint : oc.gp_Pnt;
|
||||||
|
lastPoint : oc.gp_Pnt;
|
||||||
|
wireBuilder : oc.BRepBuilderAPI_MakeWire;
|
||||||
|
|
||||||
|
Start (startingPoint : number[] ) : Sketch;
|
||||||
|
End (closed ?: boolean , reversed?:boolean) : Sketch;
|
||||||
|
AddWire (wire : oc. TopoDS_Wire) : Sketch;
|
||||||
|
|
||||||
|
LineTo (nextPoint : number[] ) : Sketch;
|
||||||
|
ArcTo (pointOnArc : number[], arcEnd : number[]) : Sketch;
|
||||||
|
BezierTo(bezierControlPoints : number[][]): Sketch;
|
||||||
|
BSplineTo(bsplinePoints : number[][]): Sketch;
|
||||||
|
/** Adds a 2D Fillet of specified radius at this vertex. Only applies to Faces!
|
||||||
|
* If a Wire is needed, use ForEachWire() to get the Wire from the resulting Face! */
|
||||||
|
Fillet (radius : number ) : Sketch;
|
||||||
|
Face (reversed ?:boolean) : oc.TopoDS_Face;
|
||||||
|
Wire (reversed ?:boolean) : oc.TopoDS_Wire;
|
||||||
|
/** Punches a circular hole in the existing face (may need to use reversed) */
|
||||||
|
Circle (center ?:number[], radius:number, reversed?:boolean) : Sketch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a solid box with dimensions x, y, and, z and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let myBox = Box(10, 20, 30);```*/
|
||||||
|
function Box(x: number, y: number, z: number, centered?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Creates a solid sphere of specified radius and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let mySphere = Sphere(40);```*/
|
||||||
|
function Sphere(radius: number): oc.TopoDS_Shape;
|
||||||
|
/** Creates a solid cylinder of specified radius and height and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let myCylinder = Cylinder(30, 50);```*/
|
||||||
|
function Cylinder(radius: number, height: number, centered?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Creates a solid cone of specified bottom radius, top radius, and height and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let myCone = Cone(30, 50);```*/
|
||||||
|
function Cone(radius1: number, radius2: number, height: number): oc.TopoDS_Shape;
|
||||||
|
/** Creates a polygon from a list of 3-component lists (points) and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let triangle = Polygon([[0, 0, 0], [50, 0, 0], [25, 50, 0]]);```*/
|
||||||
|
function Polygon(points: number[][], wire?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Creates a circle from a radius and adds it to `sceneShapes` for rendering.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let circle = Circle(50);```*/
|
||||||
|
function Circle(radius:number, wire?:boolean) : oc.TopoDS_Shape;
|
||||||
|
/** Creates a bspline from a list of 3-component lists (points).
|
||||||
|
* This can be converted into a face via the respective oc.BRepBuilderAPI functions.
|
||||||
|
* Or used directly with BRepPrimAPI_MakeRevolution()
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let bspline = BSpline([[0,0,0], [40, 0, 50], [50, 0, 50]], true);```*/
|
||||||
|
function BSpline(points:number[][], closed?:boolean) : oc.TopoDS_Shape;
|
||||||
|
/** Creates set of glyph solids from a string and a font-file and adds it to sceneShapes.
|
||||||
|
* Note that all the characters share a singular face.
|
||||||
|
*
|
||||||
|
* Defaults: size:36, height:0.15, fontName: 'Consolas'
|
||||||
|
*
|
||||||
|
* Try 'Roboto' or 'Papyrus' for an alternative typeface.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let myText = Text3D("Hello!");```*/
|
||||||
|
function Text3D(text?: string = "Hi!", size?: number = "36", height?: number = 0.15, fontURL?: string = "Consolas") : oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
|
||||||
|
/** Joins a list of shapes into a single solid.
|
||||||
|
* The original shapes are removed unless `keepObjects` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let sharpSphere = Union([Sphere(38), Box(50, 50, 50, true)]);```*/
|
||||||
|
function Union(objectsToJoin: oc.TopoDS_Shape[], keepObjects?: boolean, fuzzValue?:number, keepEdges?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Subtracts a list of shapes from mainBody.
|
||||||
|
* The original shapes are removed unless `keepObjects` is true. Returns a Compound Shape unless onlyFirstSolid is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let floatingCorners = Difference(Box(50, 50, 50, true), [Sphere(38)]);```*/
|
||||||
|
function Difference(mainBody: oc.TopoDS_Shape, objectsToSubtract: oc.TopoDS_Shape[], keepObjects?: boolean, fuzzValue?:number, keepEdges?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Takes only the intersection of a list of shapes.
|
||||||
|
* The original shapes are removed unless `keepObjects` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let roundedBox = Intersection([Box(50, 50, 50, true), Sphere(38)]);```*/
|
||||||
|
function Intersection(objectsToIntersect: oc.TopoDS_Shape[], keepObjects?: boolean, fuzzValue?: number, keepEdges?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Removes internal, unused edges from the insides of faces on this shape. Keeps the model clean.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let cleanPart = RemoveInternalEdges(part);```*/
|
||||||
|
function RemoveInternalEdges(shape: oc.TopoDS_Shape, keepShape?: boolean) : oc.TopoDS_Shape;
|
||||||
|
/** Extrudes a shape along direction, a 3-component vector. Edges form faces, Wires form shells, Faces form solids, etc.
|
||||||
|
* The original face is removed unless `keepFace` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let tallTriangle = Extrude(Polygon([[0, 0, 0], [50, 0, 0], [25, 50, 0]]), [0, 0, 50]);```*/
|
||||||
|
function Extrude(face: oc.TopoDS_Shape, direction: number[], keepFace?: boolean) : oc.TopoDS_Shape;
|
||||||
|
/** Extrudes and twists a flat *wire* upwards along the z-axis (see the optional argument for Polygon).
|
||||||
|
* The original wire is removed unless `keepWire` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let twistyTriangle = RotatedExtrude(Polygon([[-25, -15, 0], [25, -15, 0], [0, 35, 0]], true), 50, 90);```*/
|
||||||
|
function RotatedExtrude(wire: oc.TopoDS_Shape, height: number, rotation: number, keepWire?: boolean) : oc.TopoDS_Shape;
|
||||||
|
/** Lofts a solid through the sections defined by an array of 2 or more closed wires.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js) */
|
||||||
|
function Loft(wireSections: oc.TopoDS_Shape[], keepWires?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Revolves this shape "degrees" about "axis" (a 3-component array). Edges form faces, Wires form shells, Faces form solids, etc.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let cone = Revolve(Polygon([[0, 0, 0], [0, 0, 50], [50, 0, 0]]));```*/
|
||||||
|
function Revolve(shape: oc.TopoDS_Shape, degrees?: number, axis?: number[], keepShape?: boolean, copy?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Sweeps this shape along a path wire.
|
||||||
|
* The original shapes are removed unless `keepObjects` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let pipe = Pipe(Circle(20), BSpline([[0,0,0],[0,0,50],[20,0,100]], false, true));```*/
|
||||||
|
function Pipe(shape: oc.TopoDS_Shape, wirePath: oc.TopoDS_Shape, keepInputs?: boolean): oc.TopoDS_Shape;
|
||||||
|
/** Offsets the faces of a shape by offsetDistance
|
||||||
|
* The original shape is removed unless `keepShape` is true.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let roundedCube = Offset(Box(10,10,10), 10);```*/
|
||||||
|
function Offset(shape: oc.TopoDS_Shape, offsetDistance: number, tolerance?: number, keepShape?: boolean) : oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Creates a labeled slider with specified defaults, mins, and max ranges.
|
||||||
|
* @example```let currentSliderValue = Slider("Radius", 30 , 20 , 40);```
|
||||||
|
* `name` needs to be unique!
|
||||||
|
*
|
||||||
|
* `callback` triggers whenever the mouse is let go, and `realTime` will cause the slider to update every frame that there is movement (but it's buggy!)*/
|
||||||
|
function Slider(name: string, defaultValue: number, min: number, max: number, realTime?: boolean): number;
|
||||||
|
/** Creates a button that will trigger `callback` when clicked.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```Button("Yell", ()=>{ console.log("Help! I've been clicked!"); });```*/
|
||||||
|
function Button(name: string) : void;
|
||||||
|
/** Creates a checkbox that returns true or false.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let currentCheckboxValue = Checkbox("Check?", true);```
|
||||||
|
*
|
||||||
|
* `callback` triggers when the button is clicked.*/
|
||||||
|
function Checkbox(name: string, defaultValue: boolean): boolean;
|
||||||
|
|
||||||
|
/** BETA: Transform a shape using an in-view transformation gizmo.
|
||||||
|
*
|
||||||
|
* Shortcuts: `T` - Translate, `R` - Rotate, `S` - Scale, `W`/`L` - Toggle World/Local Space
|
||||||
|
*
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let transformedSphere = Transform(Sphere(50));```*/
|
||||||
|
function Transform(shape: oc.TopoDS_Shape): oc.TopoDS_Shape;
|
||||||
|
/** BETA: Transform a shape using an in-view transformation gizmo.
|
||||||
|
*
|
||||||
|
* Shortcuts: `T` - Translate, `R` - Rotate, `S` - Scale, `W`/`L` - Toggle World/Local
|
||||||
|
*
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let transformedSphere = Transform(Sphere(50));```*/
|
||||||
|
function Transform(translation: number[], rotation: (number|number[])[], scale: number, shape: oc.TopoDS_Shape, keepOriginal?: boolean): oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Translate a shape along the x, y, and z axes (using an array of 3 numbers).
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let upwardSphere = Translate([0, 0, 50], Sphere(50));```*/
|
||||||
|
function Translate(offset: number[], shape: oc.TopoDS_Shape, keepOriginal?: boolean): oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Rotate a shape degrees about a 3-coordinate axis.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let leaningCylinder = Rotate([0, 1, 0], 45, Cylinder(25, 50));```*/
|
||||||
|
function Rotate(axis: number[], degrees: number, shape: oc.TopoDS_Shape, keepOriginal?: boolean): oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Scale a shape to be `scale` times its current size.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let scaledCylinder = Scale(50, Cylinder(0.5, 1));```*/
|
||||||
|
function Scale(scale: number, shape: oc.TopoDS_Shape, keepOriginal?: boolean): oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Iterate over all the solids in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachSolid(shape: oc.TopoDS_Shape, callback: (index: Number, shell: oc.TopoDS_Solid) => void): void;
|
||||||
|
/** Gets the indexth solid from this compound shape. */
|
||||||
|
function GetSolidFromCompound(shape: oc.TopoDS_Shape, index?:number, keepOriginal?:boolean): oc.TopoDS_Solid;
|
||||||
|
/** Gets the indexth wire from this face (or above) shape. */
|
||||||
|
function GetWire(shape: oc.TopoDS_Face, index?:number, keepOriginal?:boolean): oc.TopoDS_Wire;
|
||||||
|
/** Iterate over all the shells in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachShell(shape: oc.TopoDS_Shape, callback: (index: Number, shell: oc.TopoDS_Shell) => void): void;
|
||||||
|
/** Iterate over all the faces in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachFace(shape: oc.TopoDS_Shape, callback: (index: number, face: oc.TopoDS_Face) => void): void;
|
||||||
|
/** Iterate over all the wires in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachWire(shape: oc.TopoDS_Shape, callback: (wire: oc.TopoDS_Wire) => void): void;
|
||||||
|
/** Iterate over all the UNIQUE indices and edges in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachEdge(shape: oc.TopoDS_Shape, callback: (index: number, edge: oc.TopoDS_Edge) => void): {[edgeHash:number] : Number}[];
|
||||||
|
/** Iterate over all the vertices in this shape, calling `callback` on each one. */
|
||||||
|
function ForEachVertex(shape: oc.TopoDS_Shape, callback: (vertex: oc.TopoDS_Vertex) => void): void;
|
||||||
|
/** Attempt to Fillet all selected edge indices in "edgeList" with a radius.
|
||||||
|
* Hover over the edges you'd like to select and use those indices as in the example.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```FilletEdges(shape, 1, [0,1,2,7]);``` */
|
||||||
|
function FilletEdges(shape: oc.TopoDS_Shape, radius: number, edgeList: number[], keepOriginal?:boolean): oc.TopoDS_Shape;
|
||||||
|
/** Attempt to Chamfer all selected edge indices in "edgeList" symmetrically by distance.
|
||||||
|
* Hover over the edges you'd like to select and use those indices in the edgeList array.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```ChamferEdges(shape, 1, [0,1,2,7]);``` */
|
||||||
|
function ChamferEdges(shape: oc.TopoDS_Shape, distance: number, edgeList: number[], keepOriginal?:boolean): oc.TopoDS_Shape;
|
||||||
|
|
||||||
|
/** Download this file URL through the browser. Use this to export information from the CAD engine.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```SaveFile("myInfo.txt", URL.createObjectURL( new Blob(["Hello, Harddrive!"], { type: 'text/plain' }) ));``` */
|
||||||
|
function SaveFile(filename: string, fileURL: string): void;
|
||||||
|
|
||||||
|
/** Explicitly Cache the result of this operation so that it can return instantly next time it is called with the same arguments.
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let box = CacheOp(arguments, () => { return new oc.BRepPrimAPI_MakeBox(x, y, z).Shape(); });``` */
|
||||||
|
function CacheOp(arguments: IArguments, cacheMiss: () => oc.TopoDS_Shape): oc.TopoDS_Shape;
|
||||||
|
/** Remove this object from this array. Useful for preventing objects being added to `sceneShapes` (in cached functions).
|
||||||
|
* [Source](https://github.com/zalo/CascadeStudio/blob/master/js/CADWorker/CascadeStudioStandardLibrary.js)
|
||||||
|
* @example```let box = CacheOp(arguments, () => { let box = Box(x,y,z); sceneShapes = Remove(sceneShapes, box); return box; });``` */
|
||||||
|
function Remove(array: any[], toRemove: any): any[];
|
||||||
177
web/public/Three.d.ts
vendored
Normal file
177
web/public/Three.d.ts
vendored
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
export * from './polyfills';
|
||||||
|
export * from './renderers/WebGLMultisampleRenderTarget';
|
||||||
|
export * from './renderers/WebGLCubeRenderTarget';
|
||||||
|
export * from './renderers/WebGLRenderTarget';
|
||||||
|
export * from './renderers/WebGLRenderer';
|
||||||
|
export * from './renderers/WebGL1Renderer';
|
||||||
|
export * from './renderers/shaders/ShaderLib';
|
||||||
|
export * from './renderers/shaders/UniformsLib';
|
||||||
|
export * from './renderers/shaders/UniformsUtils';
|
||||||
|
export * from './renderers/shaders/ShaderChunk';
|
||||||
|
export * from './scenes/FogExp2';
|
||||||
|
export * from './scenes/Fog';
|
||||||
|
export * from './scenes/Scene';
|
||||||
|
export * from './objects/Sprite';
|
||||||
|
export * from './objects/LOD';
|
||||||
|
export * from './objects/InstancedMesh';
|
||||||
|
export * from './objects/SkinnedMesh';
|
||||||
|
export * from './objects/Skeleton';
|
||||||
|
export * from './objects/Bone';
|
||||||
|
export * from './objects/Mesh';
|
||||||
|
export * from './objects/LineSegments';
|
||||||
|
export * from './objects/LineLoop';
|
||||||
|
export * from './objects/Line';
|
||||||
|
export * from './objects/Points';
|
||||||
|
export * from './objects/Group';
|
||||||
|
export * from './textures/VideoTexture';
|
||||||
|
export * from './textures/DataTexture';
|
||||||
|
export * from './textures/DataTexture3D';
|
||||||
|
export * from './textures/CompressedTexture';
|
||||||
|
export * from './textures/CubeTexture';
|
||||||
|
export * from './textures/CanvasTexture';
|
||||||
|
export * from './textures/DepthTexture';
|
||||||
|
export * from './textures/Texture';
|
||||||
|
export * from './geometries/Geometries';
|
||||||
|
export * from './materials/Materials';
|
||||||
|
export * from './loaders/AnimationLoader';
|
||||||
|
export * from './loaders/CompressedTextureLoader';
|
||||||
|
export * from './loaders/DataTextureLoader';
|
||||||
|
export * from './loaders/CubeTextureLoader';
|
||||||
|
export * from './loaders/TextureLoader';
|
||||||
|
export * from './loaders/ObjectLoader';
|
||||||
|
export * from './loaders/MaterialLoader';
|
||||||
|
export * from './loaders/BufferGeometryLoader';
|
||||||
|
export * from './loaders/LoadingManager';
|
||||||
|
export * from './loaders/ImageLoader';
|
||||||
|
export * from './loaders/ImageBitmapLoader';
|
||||||
|
export * from './loaders/FontLoader';
|
||||||
|
export * from './loaders/FileLoader';
|
||||||
|
export * from './loaders/Loader';
|
||||||
|
export * from './loaders/LoaderUtils';
|
||||||
|
export * from './loaders/Cache';
|
||||||
|
export * from './loaders/AudioLoader';
|
||||||
|
export * from './lights/SpotLightShadow';
|
||||||
|
export * from './lights/SpotLight';
|
||||||
|
export * from './lights/PointLight';
|
||||||
|
export * from './lights/RectAreaLight';
|
||||||
|
export * from './lights/HemisphereLight';
|
||||||
|
export * from './lights/DirectionalLightShadow';
|
||||||
|
export * from './lights/DirectionalLight';
|
||||||
|
export * from './lights/AmbientLight';
|
||||||
|
export * from './lights/LightShadow';
|
||||||
|
export * from './lights/Light';
|
||||||
|
export * from './lights/AmbientLightProbe';
|
||||||
|
export * from './lights/HemisphereLightProbe';
|
||||||
|
export * from './lights/LightProbe';
|
||||||
|
export * from './cameras/StereoCamera';
|
||||||
|
export * from './cameras/PerspectiveCamera';
|
||||||
|
export * from './cameras/OrthographicCamera';
|
||||||
|
export * from './cameras/CubeCamera';
|
||||||
|
export * from './cameras/ArrayCamera';
|
||||||
|
export * from './cameras/Camera';
|
||||||
|
export * from './audio/AudioListener';
|
||||||
|
export * from './audio/PositionalAudio';
|
||||||
|
export * from './audio/AudioContext';
|
||||||
|
export * from './audio/AudioAnalyser';
|
||||||
|
export * from './audio/Audio';
|
||||||
|
export * from './animation/tracks/VectorKeyframeTrack';
|
||||||
|
export * from './animation/tracks/StringKeyframeTrack';
|
||||||
|
export * from './animation/tracks/QuaternionKeyframeTrack';
|
||||||
|
export * from './animation/tracks/NumberKeyframeTrack';
|
||||||
|
export * from './animation/tracks/ColorKeyframeTrack';
|
||||||
|
export * from './animation/tracks/BooleanKeyframeTrack';
|
||||||
|
export * from './animation/PropertyMixer';
|
||||||
|
export * from './animation/PropertyBinding';
|
||||||
|
export * from './animation/KeyframeTrack';
|
||||||
|
export * from './animation/AnimationUtils';
|
||||||
|
export * from './animation/AnimationObjectGroup';
|
||||||
|
export * from './animation/AnimationMixer';
|
||||||
|
export * from './animation/AnimationClip';
|
||||||
|
export * from './animation/AnimationAction';
|
||||||
|
export * from './core/Uniform';
|
||||||
|
export * from './core/InstancedBufferGeometry';
|
||||||
|
export * from './core/BufferGeometry';
|
||||||
|
export * from './core/Geometry';
|
||||||
|
export * from './core/InterleavedBufferAttribute';
|
||||||
|
export * from './core/InstancedInterleavedBuffer';
|
||||||
|
export * from './core/InterleavedBuffer';
|
||||||
|
export * from './core/InstancedBufferAttribute';
|
||||||
|
export * from './core/BufferAttribute';
|
||||||
|
export * from './core/Face3';
|
||||||
|
export * from './core/Object3D';
|
||||||
|
export * from './core/Raycaster';
|
||||||
|
export * from './core/Layers';
|
||||||
|
export * from './core/EventDispatcher';
|
||||||
|
export * from './core/DirectGeometry';
|
||||||
|
export * from './core/Clock';
|
||||||
|
export * from './math/interpolants/QuaternionLinearInterpolant';
|
||||||
|
export * from './math/interpolants/LinearInterpolant';
|
||||||
|
export * from './math/interpolants/DiscreteInterpolant';
|
||||||
|
export * from './math/interpolants/CubicInterpolant';
|
||||||
|
export * from './math/Interpolant';
|
||||||
|
export * from './math/Triangle';
|
||||||
|
export * from './math/MathUtils';
|
||||||
|
export * from './math/Spherical';
|
||||||
|
export * from './math/Cylindrical';
|
||||||
|
export * from './math/Plane';
|
||||||
|
export * from './math/Frustum';
|
||||||
|
export * from './math/Sphere';
|
||||||
|
export * from './math/Ray';
|
||||||
|
export * from './math/Matrix4';
|
||||||
|
export * from './math/Matrix3';
|
||||||
|
export * from './math/Box3';
|
||||||
|
export * from './math/Box2';
|
||||||
|
export * from './math/Line3';
|
||||||
|
export * from './math/Euler';
|
||||||
|
export * from './math/Vector4';
|
||||||
|
export * from './math/Vector3';
|
||||||
|
export * from './math/Vector2';
|
||||||
|
export * from './math/Quaternion';
|
||||||
|
export * from './math/Color';
|
||||||
|
export * from './math/SphericalHarmonics3';
|
||||||
|
export * from './extras/objects/ImmediateRenderObject';
|
||||||
|
export * from './helpers/SpotLightHelper';
|
||||||
|
export * from './helpers/SkeletonHelper';
|
||||||
|
export * from './helpers/PointLightHelper';
|
||||||
|
export * from './helpers/HemisphereLightHelper';
|
||||||
|
export * from './helpers/GridHelper';
|
||||||
|
export * from './helpers/PolarGridHelper';
|
||||||
|
export * from './helpers/DirectionalLightHelper';
|
||||||
|
export * from './helpers/CameraHelper';
|
||||||
|
export * from './helpers/BoxHelper';
|
||||||
|
export * from './helpers/Box3Helper';
|
||||||
|
export * from './helpers/PlaneHelper';
|
||||||
|
export * from './helpers/ArrowHelper';
|
||||||
|
export * from './helpers/AxesHelper';
|
||||||
|
export * from './extras/curves/Curves';
|
||||||
|
export * from './extras/core/Shape';
|
||||||
|
export * from './extras/core/Path';
|
||||||
|
export * from './extras/core/ShapePath';
|
||||||
|
export * from './extras/core/Font';
|
||||||
|
export * from './extras/core/CurvePath';
|
||||||
|
export * from './extras/core/Curve';
|
||||||
|
export * from './extras/ImageUtils';
|
||||||
|
export * from './extras/ShapeUtils';
|
||||||
|
export * from './extras/PMREMGenerator';
|
||||||
|
export * from './renderers/webgl/WebGLBufferRenderer';
|
||||||
|
export * from './renderers/webgl/WebGLCapabilities';
|
||||||
|
export * from './renderers/webgl/WebGLClipping';
|
||||||
|
export * from './renderers/webgl/WebGLExtensions';
|
||||||
|
export * from './renderers/webgl/WebGLGeometries';
|
||||||
|
export * from './renderers/webgl/WebGLIndexedBufferRenderer';
|
||||||
|
export * from './renderers/webgl/WebGLInfo';
|
||||||
|
export * from './renderers/webgl/WebGLLights';
|
||||||
|
export * from './renderers/webgl/WebGLObjects';
|
||||||
|
export * from './renderers/webgl/WebGLProgram';
|
||||||
|
export * from './renderers/webgl/WebGLPrograms';
|
||||||
|
export * from './renderers/webgl/WebGLProperties';
|
||||||
|
export * from './renderers/webgl/WebGLRenderLists';
|
||||||
|
export * from './renderers/webgl/WebGLShader';
|
||||||
|
export * from './renderers/webgl/WebGLShadowMap';
|
||||||
|
export * from './renderers/webgl/WebGLState';
|
||||||
|
export * from './renderers/webgl/WebGLTextures';
|
||||||
|
export * from './renderers/webgl/WebGLUniforms';
|
||||||
|
export * from './constants';
|
||||||
|
export * from './Three.Legacy';
|
||||||
|
|
||||||
|
export as namespace THREE;
|
||||||
1644
web/public/opencascade.d.ts
vendored
Normal file
1644
web/public/opencascade.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,13 +12,18 @@ import { Router, Route } from '@redwoodjs/router'
|
|||||||
const Routes = () => {
|
const Routes = () => {
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
|
<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}" page={PartPage} name="part" />
|
||||||
|
<Route path="/parts" page={PartsPage} name="parts" />
|
||||||
<Route path="/blog-post/{id:Int}" page={BlogPostPage} name="blogPost" />
|
<Route path="/blog-post/{id:Int}" page={BlogPostPage} name="blogPost" />
|
||||||
<Route path="/posts/new" page={NewPostPage} name="newPost" />
|
<Route path="admin/posts/new" page={NewPostPage} name="newPost" />
|
||||||
<Route path="/posts/{id:Int}/edit" page={EditPostPage} name="editPost" />
|
<Route path="admin/posts/{id:Int}/edit" page={EditPostPage} name="editPost" />
|
||||||
<Route path="/posts/{id:Int}" page={PostPage} name="post" />
|
<Route path="admin/posts/{id:Int}" page={PostPage} name="post" />
|
||||||
<Route path="/posts" page={PostsPage} name="posts" />
|
<Route path="admin/posts" page={PostsPage} name="posts" />
|
||||||
<Route path="/about" page={AboutPage} name="about" />
|
<Route path="/about" page={AboutPage} name="about" />
|
||||||
<Route path="/" page={HomePage} name="home" />
|
<Route path="/" page={PartsPage} name="home" />
|
||||||
<Route notfound page={NotFoundPage} />
|
<Route notfound page={NotFoundPage} />
|
||||||
</Router>
|
</Router>
|
||||||
)
|
)
|
||||||
|
|||||||
1
web/src/cascade
Submodule
1
web/src/cascade
Submodule
Submodule web/src/cascade added at e634591e27
@@ -19,5 +19,5 @@ export const Empty = () => <div>Empty</div>
|
|||||||
export const Failure = ({ error }) => <div>Error: {error.message}</div>
|
export const Failure = ({ error }) => <div>Error: {error.message}</div>
|
||||||
|
|
||||||
export const Success = ({ posts }) => {
|
export const Success = ({ posts }) => {
|
||||||
return posts.map((post) => <BlogPost post={post} />)
|
return posts.map((post) => <BlogPost key={post.id} post={post} />)
|
||||||
}
|
}
|
||||||
51
web/src/components/EditPartCell/EditPartCell.js
Normal file
51
web/src/components/EditPartCell/EditPartCell.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||||
|
import { navigate, routes } from '@redwoodjs/router'
|
||||||
|
import PartForm from 'src/components/PartForm'
|
||||||
|
|
||||||
|
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
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
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 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
38
web/src/components/NewPart/NewPart.js
Normal file
38
web/src/components/NewPart/NewPart.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||||
|
import { navigate, routes } from '@redwoodjs/router'
|
||||||
|
import PartForm from 'src/components/PartForm'
|
||||||
|
|
||||||
|
const CREATE_PART_MUTATION = gql`
|
||||||
|
mutation CreatePartMutation($input: CreatePartInput!) {
|
||||||
|
createPart(input: $input) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const NewPart = () => {
|
||||||
|
const { addMessage } = useFlash()
|
||||||
|
const [createPart, { loading, error }] = useMutation(CREATE_PART_MUTATION, {
|
||||||
|
onCompleted: () => {
|
||||||
|
navigate(routes.parts())
|
||||||
|
addMessage('Part created.', { classes: 'rw-flash-success' })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSave = (input) => {
|
||||||
|
createPart({ variables: { input } })
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rw-segment">
|
||||||
|
<header className="rw-segment-header">
|
||||||
|
<h2 className="rw-heading rw-heading-secondary">New Part</h2>
|
||||||
|
</header>
|
||||||
|
<div className="rw-segment-main">
|
||||||
|
<PartForm onSave={onSave} loading={loading} error={error} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewPart
|
||||||
110
web/src/components/Part/Part.js
Normal file
110
web/src/components/Part/Part.js
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||||
|
import { Link, routes, navigate } from '@redwoodjs/router'
|
||||||
|
import { initialize } from 'src/cascade/js/MainPage/CascadeMain'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
const DELETE_PART_MUTATION = gql`
|
||||||
|
mutation DeletePartMutation($id: Int!) {
|
||||||
|
deletePart(id: $id) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const Part = ({ part, saveCode, loading, error}) => {
|
||||||
|
const [code, setCode] = useState(part.code)
|
||||||
|
useEffect(() => {
|
||||||
|
const sickCallback = (code) => setCode(code)
|
||||||
|
initialize(sickCallback, part.code)
|
||||||
|
}, [])
|
||||||
|
const hasChanges = code !== part.code
|
||||||
|
const { addMessage } = useFlash()
|
||||||
|
const [deletePart] = useMutation(DELETE_PART_MUTATION, {
|
||||||
|
onCompleted: () => {
|
||||||
|
navigate(routes.parts())
|
||||||
|
addMessage('Part deleted.', { classes: 'rw-flash-success' })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const onDeleteClick = (id) => {
|
||||||
|
if (confirm('Are you sure you want to delete part ' + id + '?')) {
|
||||||
|
deletePart({ variables: { id } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="rw-segment">
|
||||||
|
<header className="rw-segment-header">
|
||||||
|
<h2 className="rw-heading rw-heading-secondary">
|
||||||
|
Part {part.id} Detail
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
<table className="rw-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<td>{part.title}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Description</th>
|
||||||
|
<td>{part.description}</td>
|
||||||
|
</tr>
|
||||||
|
{/* <tr>
|
||||||
|
<th>Code</th>
|
||||||
|
<td>{part.code}</td>
|
||||||
|
</tr> */}
|
||||||
|
{/* <tr>
|
||||||
|
<th>Main image</th>
|
||||||
|
<td>{part.mainImage}</td>
|
||||||
|
</tr> */}
|
||||||
|
{/* <tr>
|
||||||
|
<th>Created at</th>
|
||||||
|
<td>{timeTag(part.createdAt)}</td>
|
||||||
|
</tr> */}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<img src={part.mainImage} />
|
||||||
|
</div>
|
||||||
|
<nav className="rw-button-group">
|
||||||
|
{loading && 'Loading...'}
|
||||||
|
{hasChanges && !loading && <button onClick={() => saveCode({code}, part.id)} className="rw-button rw-button-blue">
|
||||||
|
Save Changes
|
||||||
|
</button>}
|
||||||
|
</nav>
|
||||||
|
<div>
|
||||||
|
<div id="topnav" className="topnav">
|
||||||
|
<a href="https://github.com/zalo/CascadeStudio">Cascade Studio 0.0.6</a>
|
||||||
|
<a href="#" id="main-proj-button" title="Sets this project to save in local storage." onClick={() => makeMainProject()}>Make Main Project</a>
|
||||||
|
<a href="#" title="Save Project to .json" onClick={() => saveProject()}>Save Project</a>
|
||||||
|
<label htmlFor="project-file" title="Load Project from .json">Load Project
|
||||||
|
<input
|
||||||
|
id="project-file"
|
||||||
|
name="project-file"
|
||||||
|
type="file"
|
||||||
|
accept=".json"
|
||||||
|
style={{display:'none'}}
|
||||||
|
onInput={() => loadProject()}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeSTEP()}>Save STEP</a>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeSTL()}>Save STL</a>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeOBJ()}>Save OBJ</a>
|
||||||
|
<label htmlFor="files" title="Import STEP, IGES, or (ASCII) STL from File">Import STEP/IGES/STL
|
||||||
|
<input id="files" name="files" type="file" accept=".iges,.step,.igs,.stp,.stl" multiple style={{display: 'none'}} onInput={ () =>loadFiles()}/>
|
||||||
|
</label>
|
||||||
|
<a href="#" title="Clears the external step/iges/stl files stored in the project." onClick={() => clearExternalFiles()}>Clear Imported Files</a>
|
||||||
|
<a href="" title="Resets the project and localstorage." onClick={() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
window.history.replaceState({}, 'Cascade Studio','?')
|
||||||
|
}}>Reset Project</a>
|
||||||
|
</div>
|
||||||
|
<div id="cascade-container" style={{height:'auto'}}>
|
||||||
|
</div>
|
||||||
|
<footer>footer</footer>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Part
|
||||||
46
web/src/components/PartCell/PartCell.js
Normal file
46
web/src/components/PartCell/PartCell.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} />
|
||||||
|
}
|
||||||
100
web/src/components/PartForm/PartForm.js
Normal file
100
web/src/components/PartForm/PartForm.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormError,
|
||||||
|
FieldError,
|
||||||
|
Label,
|
||||||
|
TextField,
|
||||||
|
TextAreaField,
|
||||||
|
Submit,
|
||||||
|
} from '@redwoodjs/forms'
|
||||||
|
|
||||||
|
const PartForm = (props) => {
|
||||||
|
const onSubmit = (data) => {
|
||||||
|
props.onSave(data, props?.part?.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="title"
|
||||||
|
className="rw-label"
|
||||||
|
errorClassName="rw-label rw-label-error"
|
||||||
|
>
|
||||||
|
Title
|
||||||
|
</Label>
|
||||||
|
<TextField
|
||||||
|
name="title"
|
||||||
|
defaultValue={props.part?.title}
|
||||||
|
className="rw-input"
|
||||||
|
errorClassName="rw-input rw-input-error"
|
||||||
|
validation={{ required: true }}
|
||||||
|
/>
|
||||||
|
<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"
|
||||||
|
errorClassName="rw-label rw-label-error"
|
||||||
|
>
|
||||||
|
Main image
|
||||||
|
</Label>
|
||||||
|
<TextField
|
||||||
|
name="mainImage"
|
||||||
|
defaultValue={props.part?.mainImage}
|
||||||
|
className="rw-input"
|
||||||
|
errorClassName="rw-input rw-input-error"
|
||||||
|
validation={{ required: false }}
|
||||||
|
/>
|
||||||
|
<FieldError name="mainImage" 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 PartForm
|
||||||
109
web/src/components/Parts/Parts.js
Normal file
109
web/src/components/Parts/Parts.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||||
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
const DELETE_PART_MUTATION = gql`
|
||||||
|
mutation DeletePartMutation($id: Int!) {
|
||||||
|
deletePart(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 PartsList = ({ parts }) => {
|
||||||
|
const { addMessage } = useFlash()
|
||||||
|
const [deletePart] = useMutation(DELETE_PART_MUTATION, {
|
||||||
|
onCompleted: () => {
|
||||||
|
addMessage('Part deleted.', { classes: 'rw-flash-success' })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const onDeleteClick = (id) => {
|
||||||
|
if (confirm('Are you sure you want to delete part ' + id + '?')) {
|
||||||
|
deletePart({ variables: { id }, refetchQueries: ['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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PartsList
|
||||||
33
web/src/components/PartsCell/PartsCell.js
Normal file
33
web/src/components/PartsCell/PartsCell.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
import Parts from 'src/components/Parts'
|
||||||
|
|
||||||
|
export const QUERY = gql`
|
||||||
|
query PARTS {
|
||||||
|
parts {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
description
|
||||||
|
code
|
||||||
|
mainImage
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Loading = () => <div>Loading...</div>
|
||||||
|
|
||||||
|
export const Empty = () => {
|
||||||
|
return (
|
||||||
|
<div className="rw-text-center">
|
||||||
|
{'No parts yet. '}
|
||||||
|
<Link to={routes.newPart()} className="rw-link">
|
||||||
|
{'Create one?'}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Success = ({ parts }) => {
|
||||||
|
return <Parts parts={parts} />
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
button, input, label, textarea {
|
||||||
|
display: block;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.error, textarea.error {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,39 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
<script>
|
||||||
|
// Install Cascade Studio as a Progressive Web App for Offline Access
|
||||||
|
// This needs to be put before ANY HTTP Requests are made, so it can cache them.
|
||||||
|
var messageHandlers = {};
|
||||||
|
var cascadeStudioWorker
|
||||||
|
var workerWorking = false
|
||||||
|
var galleryProject = undefined
|
||||||
|
function coolGuy() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.register('service-worker.js').then(function(registration) {
|
||||||
|
registration.update(); // Always update the registration for the latest assets
|
||||||
|
}, function() {
|
||||||
|
console.log('Could not register Cascade Studio for offline use!');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Browser does not support offline access!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begins loading the CAD Kernel Web Worker
|
||||||
|
if (window.Worker) {
|
||||||
|
cascadeStudioWorker = new Worker('/src/cascade/js/CADWorker/CascadeStudioMainWorker.js');
|
||||||
|
// Ping Pong Messages Back and Forth based on their registration in messageHandlers
|
||||||
|
// var messageHandlers = {};
|
||||||
|
cascadeStudioWorker.onmessage = function (e) {
|
||||||
|
if(e.data.type in messageHandlers){
|
||||||
|
let response = messageHandlers[e.data.type](e.data.payload);
|
||||||
|
if (response) { cascadeStudioWorker.postMessage({ "type": e.data.type, payload: response }) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
coolGuy()
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="redwood-app"></div>
|
<div id="redwood-app"></div>
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import FatalErrorPage from 'src/pages/FatalErrorPage'
|
|||||||
import Routes from 'src/Routes'
|
import Routes from 'src/Routes'
|
||||||
|
|
||||||
import './scaffold.css'
|
import './scaffold.css'
|
||||||
|
import 'golden-layout/src/css/goldenlayout-base.css'
|
||||||
|
import 'golden-layout/src/css/goldenlayout-dark-theme.css'
|
||||||
|
import './cascade/css/main.css'
|
||||||
|
import 'monaco-editor/min/vs/editor/editor.main.css'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
|||||||
29
web/src/layouts/MainLayout/MainLayout.js
Normal file
29
web/src/layouts/MainLayout/MainLayout.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
const MainLayout = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Link to={routes.about()}>About</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link to={routes.home()}>Home</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link to={routes.parts()}>Parts</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link to={routes.contact()}>Contact</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>{children}</main>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MainLayout
|
||||||
7
web/src/layouts/MainLayout/MainLayout.stories.js
Normal file
7
web/src/layouts/MainLayout/MainLayout.stories.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import MainLayout from './MainLayout'
|
||||||
|
|
||||||
|
export const generated = () => {
|
||||||
|
return <MainLayout />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { title: 'Layouts/MainLayout' }
|
||||||
11
web/src/layouts/MainLayout/MainLayout.test.js
Normal file
11
web/src/layouts/MainLayout/MainLayout.test.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { render } from '@redwoodjs/testing'
|
||||||
|
|
||||||
|
import MainLayout from './MainLayout'
|
||||||
|
|
||||||
|
describe('MainLayout', () => {
|
||||||
|
it('renders successfully', () => {
|
||||||
|
expect(() => {
|
||||||
|
render(<MainLayout />)
|
||||||
|
}).not.toThrow()
|
||||||
|
})
|
||||||
|
})
|
||||||
23
web/src/layouts/PartsLayout/PartsLayout.js
Normal file
23
web/src/layouts/PartsLayout/PartsLayout.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PartsLayout
|
||||||
59
web/src/pages/ContactPage/ContactPage.js
Normal file
59
web/src/pages/ContactPage/ContactPage.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { Form, TextField, Submit, TextAreaField, FieldError, FormError } from '@redwoodjs/forms'
|
||||||
|
import { useMutation, Flash, useFlash } from '@redwoodjs/web'
|
||||||
|
import MainLayout from 'src/layouts/MainLayout'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
|
||||||
|
const CREATE_CONTACT = gql`
|
||||||
|
mutation CreateContactMutation($input: CreateContactInput!) {
|
||||||
|
createContact(input: $input) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const ContactPage = () => {
|
||||||
|
const formMethods = useForm()
|
||||||
|
const { addMessage } = useFlash()
|
||||||
|
const [create, {loading, error}] = useMutation(CREATE_CONTACT, {
|
||||||
|
onCompleted: () => {
|
||||||
|
addMessage('Thank you for your submission!', {
|
||||||
|
style: { backgroundColor: 'green', color: 'white', padding: '1rem' }
|
||||||
|
})
|
||||||
|
formMethods.reset()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
try {
|
||||||
|
await create({ variables: { input: data } })
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MainLayout>
|
||||||
|
<Flash timeout={2000} />
|
||||||
|
<Form onSubmit={onSubmit} validation={{ mode: 'onBlur' }} error={error} formMethods={formMethods}>
|
||||||
|
<FormError
|
||||||
|
error={error}
|
||||||
|
wrapperStyle={{ color: 'red', backgroundColor: 'lavenderblush' }}
|
||||||
|
/>
|
||||||
|
<label htmlFor="name">Name</label>
|
||||||
|
<TextField name="name" validation={{required: true}} errorClassName="error" />
|
||||||
|
<FieldError name="name" className="error" />
|
||||||
|
|
||||||
|
<label htmlFor="email">Email</label>
|
||||||
|
<TextField name="email" validation={{required: true}} errorClassName="error" />
|
||||||
|
<FieldError name="email" className="error" />
|
||||||
|
|
||||||
|
<label htmlFor="message">Message</label>
|
||||||
|
<TextAreaField name="message" validation={{required: true}} errorClassName="error" />
|
||||||
|
<FieldError name="message" className="error" />
|
||||||
|
|
||||||
|
<Submit disabled={loading}>Save</Submit>
|
||||||
|
</Form>
|
||||||
|
</MainLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ContactPage
|
||||||
7
web/src/pages/ContactPage/ContactPage.stories.js
Normal file
7
web/src/pages/ContactPage/ContactPage.stories.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import ContactPage from './ContactPage'
|
||||||
|
|
||||||
|
export const generated = () => {
|
||||||
|
return <ContactPage />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { title: 'Pages/ContactPage' }
|
||||||
11
web/src/pages/ContactPage/ContactPage.test.js
Normal file
11
web/src/pages/ContactPage/ContactPage.test.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { render } from '@redwoodjs/testing'
|
||||||
|
|
||||||
|
import ContactPage from './ContactPage'
|
||||||
|
|
||||||
|
describe('ContactPage', () => {
|
||||||
|
it('renders successfully', () => {
|
||||||
|
expect(() => {
|
||||||
|
render(<ContactPage />)
|
||||||
|
}).not.toThrow()
|
||||||
|
})
|
||||||
|
})
|
||||||
12
web/src/pages/EditPartPage/EditPartPage.js
Normal file
12
web/src/pages/EditPartPage/EditPartPage.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import PartsLayout from 'src/layouts/PartsLayout'
|
||||||
|
import EditPartCell from 'src/components/EditPartCell'
|
||||||
|
|
||||||
|
const EditPartPage = ({ id }) => {
|
||||||
|
return (
|
||||||
|
<PartsLayout>
|
||||||
|
<EditPartCell id={id} />
|
||||||
|
</PartsLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditPartPage
|
||||||
@@ -1,12 +1,75 @@
|
|||||||
import BlogLayout from 'src/layouts/BlogLayout'
|
import MainLayout from 'src/layouts/MainLayout'
|
||||||
import BlogPostsCell from 'src/components/BlogPostsCell'
|
import BlogPostsCell from 'src/components/BlogPostsCell'
|
||||||
|
import { initialize } from 'src/cascade/js/MainPage/CascadeMain'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
const starterCode =
|
||||||
|
`// Welcome to Cascade Studio! Here are some useful functions:
|
||||||
|
// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()
|
||||||
|
// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()
|
||||||
|
// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),
|
||||||
|
// FilletEdges(), ChamferEdges(),
|
||||||
|
// Slider(), Button(), Checkbox()
|
||||||
|
|
||||||
|
// Uncomment and hover over them to see their apis
|
||||||
|
|
||||||
|
let holeRadius = Slider("Radius", 30 , 20 , 40);
|
||||||
|
|
||||||
|
let sphere = Sphere(50);
|
||||||
|
let cylinderZ = Cylinder(holeRadius, 200, true);
|
||||||
|
let cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));
|
||||||
|
let cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));
|
||||||
|
|
||||||
|
Translate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));
|
||||||
|
|
||||||
|
Translate([-100, 0, 100], Text3D("cadhub.xyz"));
|
||||||
|
|
||||||
|
// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!
|
||||||
|
`;
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
|
const [code, setCode] = useState(starterCode)
|
||||||
|
useEffect(() => {
|
||||||
|
const sickCallback = (code) => setCode(code)
|
||||||
|
new initialize(sickCallback, starterCode)
|
||||||
|
}, [])
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<BlogLayout>
|
<MainLayout>
|
||||||
|
<div>current code {code}</div>
|
||||||
<BlogPostsCell/>
|
<BlogPostsCell/>
|
||||||
</BlogLayout>
|
<div>
|
||||||
|
<div id="topnav" className="topnav">
|
||||||
|
<a href="https://github.com/zalo/CascadeStudio">Cascade Studio 0.0.6</a>
|
||||||
|
<a href="#" id="main-proj-button" title="Sets this project to save in local storage." onClick={() => makeMainProject()}>Make Main Project</a>
|
||||||
|
<a href="#" title="Save Project to .json" onClick={() => saveProject()}>Save Project</a>
|
||||||
|
<label htmlFor="project-file" title="Load Project from .json">Load Project
|
||||||
|
<input
|
||||||
|
id="project-file"
|
||||||
|
name="project-file"
|
||||||
|
type="file"
|
||||||
|
accept=".json"
|
||||||
|
style={{display:'none'}}
|
||||||
|
onInput={() => loadProject()}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeSTEP()}>Save STEP</a>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeSTL()}>Save STL</a>
|
||||||
|
<a href="#" onClick={() => threejsViewport.saveShapeOBJ()}>Save OBJ</a>
|
||||||
|
<label htmlFor="files" title="Import STEP, IGES, or (ASCII) STL from File">Import STEP/IGES/STL
|
||||||
|
<input id="files" name="files" type="file" accept=".iges,.step,.igs,.stp,.stl" multiple style={{display: 'none'}} onInput={ () =>loadFiles()}/>
|
||||||
|
</label>
|
||||||
|
<a href="#" title="Clears the external step/iges/stl files stored in the project." onClick={() => clearExternalFiles()}>Clear Imported Files</a>
|
||||||
|
<a href="" title="Resets the project and localstorage." onClick={() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
window.history.replaceState({}, 'Cascade Studio','?')
|
||||||
|
}}>Reset Project</a>
|
||||||
|
</div>
|
||||||
|
<div id="cascade-container" style={{height:'auto'}}>
|
||||||
|
</div>
|
||||||
|
<footer>footer</footer>
|
||||||
|
</div>
|
||||||
|
</MainLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
web/src/pages/NewPartPage/NewPartPage.js
Normal file
12
web/src/pages/NewPartPage/NewPartPage.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import PartsLayout from 'src/layouts/PartsLayout'
|
||||||
|
import NewPart from 'src/components/NewPart'
|
||||||
|
|
||||||
|
const NewPartPage = () => {
|
||||||
|
return (
|
||||||
|
<PartsLayout>
|
||||||
|
<NewPart />
|
||||||
|
</PartsLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewPartPage
|
||||||
15
web/src/pages/PartPage/PartPage.js
Normal file
15
web/src/pages/PartPage/PartPage.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import PartsLayout from 'src/layouts/PartsLayout'
|
||||||
|
import MainLayout from 'src/layouts/MainLayout'
|
||||||
|
import PartCell from 'src/components/PartCell'
|
||||||
|
|
||||||
|
const PartPage = ({ id }) => {
|
||||||
|
return (
|
||||||
|
<MainLayout>
|
||||||
|
<PartsLayout>
|
||||||
|
<PartCell id={id} />
|
||||||
|
</PartsLayout>
|
||||||
|
</MainLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PartPage
|
||||||
15
web/src/pages/PartsPage/PartsPage.js
Normal file
15
web/src/pages/PartsPage/PartsPage.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import MainLayout from 'src/layouts/MainLayout'
|
||||||
|
import PartsLayout from 'src/layouts/PartsLayout'
|
||||||
|
import PartsCell from 'src/components/PartsCell'
|
||||||
|
|
||||||
|
const PartsPage = () => {
|
||||||
|
return (
|
||||||
|
<MainLayout>
|
||||||
|
<PartsLayout>
|
||||||
|
<PartsCell />
|
||||||
|
</PartsLayout>
|
||||||
|
</MainLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PartsPage
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
|
import MainLayout from 'src/layouts/MainLayout'
|
||||||
import PostsLayout from 'src/layouts/PostsLayout'
|
import PostsLayout from 'src/layouts/PostsLayout'
|
||||||
import PostsCell from 'src/components/PostsCell'
|
import PostsCell from 'src/components/PostsCell'
|
||||||
|
|
||||||
const PostsPage = () => {
|
const PostsPage = () => {
|
||||||
return (
|
return (
|
||||||
|
<MainLayout>
|
||||||
<PostsLayout>
|
<PostsLayout>
|
||||||
<PostsCell />
|
<PostsCell />
|
||||||
</PostsLayout>
|
</PostsLayout>
|
||||||
|
</MainLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
39
yarn.lock
39
yarn.lock
@@ -5874,6 +5874,11 @@ content-type@~1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||||
|
|
||||||
|
controlkit@^0.1.9:
|
||||||
|
version "0.1.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/controlkit/-/controlkit-0.1.9.tgz#00a0598a2a3c25f85494327d86d3daf1b11f08ab"
|
||||||
|
integrity sha1-AKBZiio8JfhUlDJ9htPa8bEfCKs=
|
||||||
|
|
||||||
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
|
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
||||||
@@ -8235,6 +8240,13 @@ globby@^6.1.0:
|
|||||||
pify "^2.0.0"
|
pify "^2.0.0"
|
||||||
pinkie-promise "^2.0.0"
|
pinkie-promise "^2.0.0"
|
||||||
|
|
||||||
|
golden-layout@^1.5.9:
|
||||||
|
version "1.5.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/golden-layout/-/golden-layout-1.5.9.tgz#a39bc1f6a67e6f886b797c016dd924e9426ba77f"
|
||||||
|
integrity sha1-o5vB9qZ+b4hreXwBbdkk6UJrp38=
|
||||||
|
dependencies:
|
||||||
|
jquery "*"
|
||||||
|
|
||||||
good-listener@^1.2.2:
|
good-listener@^1.2.2:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
|
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
|
||||||
@@ -9892,6 +9904,11 @@ jest@^26.1.0:
|
|||||||
import-local "^3.0.2"
|
import-local "^3.0.2"
|
||||||
jest-cli "^26.2.2"
|
jest-cli "^26.2.2"
|
||||||
|
|
||||||
|
jquery@*, jquery@^3.5.1:
|
||||||
|
version "3.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5"
|
||||||
|
integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==
|
||||||
|
|
||||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
@@ -10919,6 +10936,18 @@ module-not-found-error@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0"
|
resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0"
|
||||||
integrity sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=
|
integrity sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=
|
||||||
|
|
||||||
|
monaco-editor-webpack-plugin@^1.9.1:
|
||||||
|
version "1.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.1.tgz#eb4bbb1c5e5bfb554541c1ae1542e74c2a9f43fd"
|
||||||
|
integrity sha512-x7fx1w3i/uwZERIgztHAAK3VQMsL8+ku0lFXXbO81hKDg8IieACqjGEa2mqEueg0c/fX+wd0oI+75wB19KJAsA==
|
||||||
|
dependencies:
|
||||||
|
loader-utils "^1.2.3"
|
||||||
|
|
||||||
|
monaco-editor@^0.20.0:
|
||||||
|
version "0.20.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea"
|
||||||
|
integrity sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ==
|
||||||
|
|
||||||
morgan@^1.10.0:
|
morgan@^1.10.0:
|
||||||
version "1.10.0"
|
version "1.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
|
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
|
||||||
@@ -11433,6 +11462,11 @@ open@^7.0.0:
|
|||||||
is-docker "^2.0.0"
|
is-docker "^2.0.0"
|
||||||
is-wsl "^2.1.1"
|
is-wsl "^2.1.1"
|
||||||
|
|
||||||
|
opencascade.js@^0.1.15:
|
||||||
|
version "0.1.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/opencascade.js/-/opencascade.js-0.1.19.tgz#32d545ca4add213d168eb6e6973dceba1bcab35b"
|
||||||
|
integrity sha512-7q8LNihtU7BzsIXXoqTHq2/7ASfDdK5OycuI1oscc/9Opmew8OXjcv/oTSF+w5U+0dwUt8LewdG/xYSIkkf8Ig==
|
||||||
|
|
||||||
opener@^1.5.1:
|
opener@^1.5.1:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
|
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
|
||||||
@@ -14166,6 +14200,11 @@ text-table@0.2.0, text-table@^0.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||||
|
|
||||||
|
three@^0.118.3:
|
||||||
|
version "0.118.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/three/-/three-0.118.3.tgz#c0bf8c10a68155478f12f4ccac2ff979526a4a0a"
|
||||||
|
integrity sha512-ijECXrNzDkHieoeh2H69kgawTGH8DiamhR4uBN8jEM7VHSKvfTdEvOoHsA8Aq7dh7PHAxhlqBsN5arBI3KixSw==
|
||||||
|
|
||||||
throat@^5.0.0:
|
throat@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
||||||
|
|||||||
Reference in New Issue
Block a user