1 Commits

Author SHA1 Message Date
Eric Tuvesson
1190dbdf89 feat: Slider add children to thumb
I am not super happy with how this works as the child is inside the thumb div. Ideally it should be moving around the thumb, but then that might be a tooltip lib?
2024-05-21 16:47:16 +02:00
85 changed files with 635 additions and 1026 deletions

View File

@@ -1,4 +1,4 @@
name: Build fluxscape-editor name: Build noodl-editor
on: on:
# Allows you to run this workflow manually from the Actions tab # Allows you to run this workflow manually from the Actions tab
@@ -72,6 +72,6 @@ jobs:
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: fluxscape-editor-${{ matrix.platform }}-${{ github.head_ref }}-${{ github.sha }} name: noodl-editor-${{ matrix.platform }}-${{ github.head_ref }}-${{ github.sha }}
path: publish path: publish
retention-days: '12' retention-days: "12"

View File

@@ -1,4 +1,4 @@
name: Test fluxscape-editor name: Test noodl-editor
on: on:
# Allows you to run this workflow manually from the Actions tab # Allows you to run this workflow manually from the Actions tab

View File

@@ -1,21 +1,21 @@
# Fluxscape # Noodl
Fluxscape is a low-code platform where designers and developers build custom applications and experiences. Designed as a visual programming environment, it aims to expedite your development process. It promotes the swift and efficient creation of applications, requiring minimal coding knowledge. [Noodl](https://noodl.net) is a low-code platform where designers and developers build custom applications and experiences. Designed as a visual programming environment, it aims to expedite your development process. It promotes the swift and efficient creation of applications, requiring minimal coding knowledge.
## Documentation ## Documentation
Documentation for how to use Fluxscape can be found here: Documentation for how to use Noodl can be found here:
[Fluxscape Documentation](https://docs.fluxscape.io) [https://noodlapp.github.io/noodl-docs/](https://noodlapp.github.io/noodl-docs/)
## Community ## Community
Main support channel is Discord: [Fluxscape Discord](https://discord.gg/fXNW9EXa6A) Main support channel is Discord: [https://www.noodl.net/community](https://www.noodl.net/community)
## Download releases ## Download releases
Pre-built binaries can be [downloaded from Github](https://github.com/fluxscape/fluxscape/releases) Pre-built binaries can be [downloaded from Github](https://github.com/noodlapp/noodl/releases)
## Note for users who are migrating from the deprecated closed source version ## Note for users who are migrating from the deprecated closed source version
- [Migrating the project files and workspaces to a Git provider](https://docs.fluxscape.io/docs/guides/collaboration/migrating-from-noodl-hosted-git/) - [Migrating the project files and workspaces to a Git provider](https://noodlapp.github.io/noodl-docs/docs/guides/collaboration/migrating-from-noodl-hosted-git)
- [Migrate backend and database](https://docs.fluxscape.io/docs/guides/deploy/using-an-external-backend/#migrating-from-a-noodl-cloud-service) - [Migrate backend and database](https://noodlapp.github.io/noodl-docs/docs/guides/deploy/using-an-external-backend#migrating-from-a-noodl-cloud-service)
- [Self-host frontend](https://docs.fluxscape.io/docs/guides/deploy/hosting-frontend/) - [Self-host frontend](https://noodlapp.github.io/noodl-docs/docs/guides/deploy/hosting-frontend)
## Building from source ## Building from source
@@ -23,24 +23,24 @@ Pre-built binaries can be [downloaded from Github](https://github.com/fluxscape/
# Install all dependencies # Install all dependencies
$ npm install $ npm install
# Start the Fluxscape Editor and build a production version of the cloud and react runtime (useful when running Fluxscape from source but want to deploy to production) # Start the Noodl Editor and build a production version of the cloud and react runtime (useful when running Noodl from source but want to deploy to production)
$ npm start $ npm start
# Start the Fluxscape Editor and watch the filesystem for changes to the runtimes. Development versions of the runtimes, not meant for production (mostly due to source maps and file size) # Start the Noodl Editor and watch the filesystem for changes to the runtimes. Development versions of the runtimes, not meant for production (mostly due to source maps and file size)
# This is ideal for a quick workflow when doing changes on the runtimes. # This is ideal for a quick workflow when doing changes on the runtimes.
$ npm run dev $ npm run dev
# Start Fluxscape Editor test runner # Start Noodl Editor test runner
$ npm run test:editor $ npm run test:editor
``` ```
## Licenses ## Licenses
This repository contains two different licenses for different parts of the Fluxscape platform. This repository contains two different licenses for different parts of the Noodl platform.
- Components related to the editor, used to edit Fluxscape projects, are under GPLv3 - Components related to the editor, used to edit Noodl projects, are under GPLv3
- Components related to the end applications, used by the applications Fluxscape deploys, are under MIT - Components related to the end applications, used by the applications Noodl deploys, are under MIT
All of the source code of applications created with Fluxscape are under MIT. This means you can do project specific changes to the runtime without having to redistribute your changes. All of the source code of applications created with Noodl are under MIT. This means you can do project specific changes to the runtime without having to redistribute your changes.
Packaged licensed under MIT: Packaged licensed under MIT:
- `noodl-runtime` - `noodl-runtime`

347
package-lock.json generated
View File

@@ -2849,9 +2849,9 @@
} }
}, },
"node_modules/@electron/remote": { "node_modules/@electron/remote": {
"version": "2.1.2", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.2.tgz", "resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.1.tgz",
"integrity": "sha512-EPwNx+nhdrTBxyCqXt/pftoQg/ybtWDW3DUWHafejvnB1ZGGfMpv6e15D8KeempocjXe78T7WreyGGb3mlZxdA==", "integrity": "sha512-Lfxul2yBxL+FBVaKszNAkuUqSIDbUQ1I7BC394iRXyqA2XGz7im2bAxroNIM51jhySSPKUaOLHaFLxfV6pC9VQ==",
"peerDependencies": { "peerDependencies": {
"electron": ">= 13.0.0" "electron": ">= 13.0.0"
} }
@@ -25220,13 +25220,13 @@
} }
}, },
"node_modules/electron": { "node_modules/electron": {
"version": "31.3.1", "version": "28.1.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.3.1.tgz", "resolved": "https://registry.npmjs.org/electron/-/electron-28.1.4.tgz",
"integrity": "sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==", "integrity": "sha512-WE6go611KOhtH6efRPMnVC7FE7DCKnQ3ZyHFeI1DbaCy8OU4UjZ8/CZGcuZmZgRdxSBEHoHdgaJkWRHZzF0FOg==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@electron/get": "^2.0.0", "@electron/get": "^2.0.0",
"@types/node": "^20.9.0", "@types/node": "^18.11.18",
"extract-zip": "^2.0.1" "extract-zip": "^2.0.1"
}, },
"bin": { "bin": {
@@ -25452,14 +25452,6 @@
"tiny-typed-emitter": "^2.1.0" "tiny-typed-emitter": "^2.1.0"
} }
}, },
"node_modules/electron/node_modules/@types/node": {
"version": "20.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz",
"integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/elliptic": { "node_modules/elliptic": {
"version": "6.5.4", "version": "6.5.4",
"dev": true, "dev": true,
@@ -27211,10 +27203,6 @@
"react": "^15.0.2 || ^16.0.0 || ^17.0.0" "react": "^15.0.2 || ^16.0.0 || ^17.0.0"
} }
}, },
"node_modules/fluxscape-editor": {
"resolved": "packages/noodl-editor",
"link": true
},
"node_modules/focus-lock": { "node_modules/focus-lock": {
"version": "0.8.1", "version": "0.8.1",
"dev": true, "dev": true,
@@ -35455,6 +35443,10 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/noodl-editor": {
"resolved": "packages/noodl-editor",
"link": true
},
"node_modules/nopt": { "node_modules/nopt": {
"version": "1.0.10", "version": "1.0.10",
"license": "MIT", "license": "MIT",
@@ -43199,11 +43191,6 @@
"version": "1.13.6", "version": "1.13.6",
"license": "MIT" "license": "MIT"
}, },
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/unfetch": { "node_modules/unfetch": {
"version": "4.2.0", "version": "4.2.0",
"dev": true, "dev": true,
@@ -48980,10 +48967,9 @@
"dev": true "dev": true
}, },
"packages/noodl-editor": { "packages/noodl-editor": {
"name": "fluxscape-editor", "version": "1.0.0",
"version": "1.1.0",
"dependencies": { "dependencies": {
"@electron/remote": "^2.1.2", "@electron/remote": "^2.1.1",
"@jaames/iro": "^5.5.2", "@jaames/iro": "^5.5.2",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@noodl/git": "file:../noodl-git", "@noodl/git": "file:../noodl-git",
@@ -49039,7 +49025,7 @@
"babel-loader": "^8.2.4", "babel-loader": "^8.2.4",
"concurrently": "^7.4.0", "concurrently": "^7.4.0",
"css-loader": "^6.7.1", "css-loader": "^6.7.1",
"electron": "31.3.1", "electron": "28.1.4",
"electron-builder": "^24.9.1", "electron-builder": "^24.9.1",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"html-loader": "^3.1.0", "html-loader": "^3.1.0",
@@ -53389,9 +53375,9 @@
} }
}, },
"@electron/remote": { "@electron/remote": {
"version": "2.1.2", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.2.tgz", "resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.1.tgz",
"integrity": "sha512-EPwNx+nhdrTBxyCqXt/pftoQg/ybtWDW3DUWHafejvnB1ZGGfMpv6e15D8KeempocjXe78T7WreyGGb3mlZxdA==", "integrity": "sha512-Lfxul2yBxL+FBVaKszNAkuUqSIDbUQ1I7BC394iRXyqA2XGz7im2bAxroNIM51jhySSPKUaOLHaFLxfV6pC9VQ==",
"requires": {} "requires": {}
}, },
"@electron/universal": { "@electron/universal": {
@@ -74071,23 +74057,13 @@
} }
}, },
"electron": { "electron": {
"version": "31.3.1", "version": "28.1.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.3.1.tgz", "resolved": "https://registry.npmjs.org/electron/-/electron-28.1.4.tgz",
"integrity": "sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==", "integrity": "sha512-WE6go611KOhtH6efRPMnVC7FE7DCKnQ3ZyHFeI1DbaCy8OU4UjZ8/CZGcuZmZgRdxSBEHoHdgaJkWRHZzF0FOg==",
"requires": { "requires": {
"@electron/get": "^2.0.0", "@electron/get": "^2.0.0",
"@types/node": "^20.9.0", "@types/node": "^18.11.18",
"extract-zip": "^2.0.1" "extract-zip": "^2.0.1"
},
"dependencies": {
"@types/node": {
"version": "20.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz",
"integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==",
"requires": {
"undici-types": "~5.26.4"
}
}
} }
}, },
"electron-builder": { "electron-builder": {
@@ -75432,144 +75408,6 @@
"fbjs": "^3.0.1" "fbjs": "^3.0.1"
} }
}, },
"fluxscape-editor": {
"version": "file:packages/noodl-editor",
"requires": {
"@babel/core": "^7.19.1",
"@babel/preset-react": "^7.18.6",
"@electron/remote": "^2.1.2",
"@jaames/iro": "^5.5.2",
"@microsoft/fetch-event-source": "^2.0.1",
"@noodl/git": "file:../noodl-git",
"@noodl/noodl-parse-dashboard": "file:../noodl-parse-dashboard",
"@noodl/platform": "file:../noodl-platform",
"@noodl/platform-electron": "file:../noodl-platform-electron",
"@svgr/webpack": "^6.4.0",
"@types/checksum": "^0.1.33",
"@types/jasmine": "^4.3.0",
"@types/jquery": "^3.5.14",
"@types/react": "^17.0.50",
"@types/react-dom": "^18.0.0",
"@types/remarkable": "^2.0.3",
"@types/rimraf": "^3.0.2",
"@types/split2": "^3.2.1",
"@types/string.prototype.matchall": "^4.0.1",
"@types/underscore": "^1.11.4",
"@types/webpack-env": "^1.18.0",
"about-window": "^1.15.2",
"algoliasearch": "^4.14.2",
"archiver": "^5.3.0",
"async": "^3.2.4",
"babel-loader": "^8.2.4",
"classnames": "^2.3.2",
"concurrently": "^7.4.0",
"css-loader": "^6.7.1",
"diff3": "0.0.4",
"dmg-license": "^1.0.11",
"electron": "31.3.1",
"electron-builder": "^24.9.1",
"electron-store": "^8.1.0",
"electron-updater": "^6.1.7",
"express": "^4.17.3",
"file-loader": "^6.2.0",
"highlight.js": "^11.5.1",
"html-loader": "^3.1.0",
"isbinaryfile": "^5.0.0",
"md5": "^2.3.0",
"md5-file": "^5.0.0",
"mixpanel-browser": "^2.45.0",
"mkdirp": "0.5.1",
"mkdirp-sync": "0.0.2",
"monaco-editor": "^0.34.0",
"monaco-editor-webpack-plugin": "^7.0.1",
"ncp": "^2.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.0",
"react-hot-toast": "^2.4.0",
"react-instantsearch-hooks-web": "^6.38.0",
"react-json-view": "^1.21.3",
"react-rnd": "^10.3.7",
"remarkable": "^2.0.1",
"rimraf": "^3.0.2",
"s3": "git+https://github.com/noodlapp/node-s3-client.git",
"sass": "^1.55.0",
"sass-loader": "^12.6.0",
"string.prototype.matchall": "^4.0.7",
"stringify": "^5.2.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.4.1",
"ts-node": "^10.7.0",
"typescript": "^4.8.3",
"underscore": "^1.13.6",
"url-loader": "^4.1.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0",
"websocket-stream": "^5.5.2",
"ws": "^8.9.0"
},
"dependencies": {
"@webpack-cli/configtest": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
"integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
"dev": true,
"requires": {}
},
"@webpack-cli/info": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
"integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
"dev": true,
"requires": {
"envinfo": "^7.7.3"
}
},
"@webpack-cli/serve": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
"integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
"dev": true,
"requires": {}
},
"commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"dev": true
},
"rechoir": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
"integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
"dev": true,
"requires": {
"resolve": "^1.9.0"
}
},
"webpack-cli": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
"integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
"dev": true,
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.2.0",
"@webpack-cli/info": "^1.5.0",
"@webpack-cli/serve": "^1.7.0",
"colorette": "^2.0.14",
"commander": "^7.0.0",
"cross-spawn": "^7.0.3",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2",
"interpret": "^2.2.0",
"rechoir": "^0.7.0",
"webpack-merge": "^5.7.3"
}
}
}
},
"focus-lock": { "focus-lock": {
"version": "0.8.1", "version": "0.8.1",
"dev": true, "dev": true,
@@ -81145,6 +80983,144 @@
"version": "2.0.10", "version": "2.0.10",
"dev": true "dev": true
}, },
"noodl-editor": {
"version": "file:packages/noodl-editor",
"requires": {
"@babel/core": "^7.19.1",
"@babel/preset-react": "^7.18.6",
"@electron/remote": "^2.1.1",
"@jaames/iro": "^5.5.2",
"@microsoft/fetch-event-source": "^2.0.1",
"@noodl/git": "file:../noodl-git",
"@noodl/noodl-parse-dashboard": "file:../noodl-parse-dashboard",
"@noodl/platform": "file:../noodl-platform",
"@noodl/platform-electron": "file:../noodl-platform-electron",
"@svgr/webpack": "^6.4.0",
"@types/checksum": "^0.1.33",
"@types/jasmine": "^4.3.0",
"@types/jquery": "^3.5.14",
"@types/react": "^17.0.50",
"@types/react-dom": "^18.0.0",
"@types/remarkable": "^2.0.3",
"@types/rimraf": "^3.0.2",
"@types/split2": "^3.2.1",
"@types/string.prototype.matchall": "^4.0.1",
"@types/underscore": "^1.11.4",
"@types/webpack-env": "^1.18.0",
"about-window": "^1.15.2",
"algoliasearch": "^4.14.2",
"archiver": "^5.3.0",
"async": "^3.2.4",
"babel-loader": "^8.2.4",
"classnames": "^2.3.2",
"concurrently": "^7.4.0",
"css-loader": "^6.7.1",
"diff3": "0.0.4",
"dmg-license": "^1.0.11",
"electron": "28.1.4",
"electron-builder": "^24.9.1",
"electron-store": "^8.1.0",
"electron-updater": "^6.1.7",
"express": "^4.17.3",
"file-loader": "^6.2.0",
"highlight.js": "^11.5.1",
"html-loader": "^3.1.0",
"isbinaryfile": "^5.0.0",
"md5": "^2.3.0",
"md5-file": "^5.0.0",
"mixpanel-browser": "^2.45.0",
"mkdirp": "0.5.1",
"mkdirp-sync": "0.0.2",
"monaco-editor": "^0.34.0",
"monaco-editor-webpack-plugin": "^7.0.1",
"ncp": "^2.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.0",
"react-hot-toast": "^2.4.0",
"react-instantsearch-hooks-web": "^6.38.0",
"react-json-view": "^1.21.3",
"react-rnd": "^10.3.7",
"remarkable": "^2.0.1",
"rimraf": "^3.0.2",
"s3": "git+https://github.com/noodlapp/node-s3-client.git",
"sass": "^1.55.0",
"sass-loader": "^12.6.0",
"string.prototype.matchall": "^4.0.7",
"stringify": "^5.2.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.4.1",
"ts-node": "^10.7.0",
"typescript": "^4.8.3",
"underscore": "^1.13.6",
"url-loader": "^4.1.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0",
"websocket-stream": "^5.5.2",
"ws": "^8.9.0"
},
"dependencies": {
"@webpack-cli/configtest": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
"integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
"dev": true,
"requires": {}
},
"@webpack-cli/info": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
"integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
"dev": true,
"requires": {
"envinfo": "^7.7.3"
}
},
"@webpack-cli/serve": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
"integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
"dev": true,
"requires": {}
},
"commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"dev": true
},
"rechoir": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
"integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
"dev": true,
"requires": {
"resolve": "^1.9.0"
}
},
"webpack-cli": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
"integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
"dev": true,
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.2.0",
"@webpack-cli/info": "^1.5.0",
"@webpack-cli/serve": "^1.7.0",
"colorette": "^2.0.14",
"commander": "^7.0.0",
"cross-spawn": "^7.0.3",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2",
"interpret": "^2.2.0",
"rechoir": "^0.7.0",
"webpack-merge": "^5.7.3"
}
}
}
},
"nopt": { "nopt": {
"version": "1.0.10", "version": "1.0.10",
"requires": { "requires": {
@@ -86427,11 +86403,6 @@
"underscore": { "underscore": {
"version": "1.13.6" "version": "1.13.6"
}, },
"undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"unfetch": { "unfetch": {
"version": "4.2.0", "version": "4.2.0",
"dev": true "dev": true

View File

@@ -2,8 +2,8 @@
"private": true, "private": true,
"name": "@noodl/repo", "name": "@noodl/repo",
"description": "Low-code for when experience matter", "description": "Low-code for when experience matter",
"author": "Fluxscape <contact@fluxcsape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io", "homepage": "https://noodl.net",
"version": "1.0.0", "version": "1.0.0",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
@@ -12,7 +12,7 @@
"graph": "npx nx graph", "graph": "npx nx graph",
"ci:prepare:editor": "ts-node ./scripts/ci-editor-prepare.ts", "ci:prepare:editor": "ts-node ./scripts/ci-editor-prepare.ts",
"ci:build:viewer": "lerna exec --scope @noodl/noodl-viewer-react -- npm run build", "ci:build:viewer": "lerna exec --scope @noodl/noodl-viewer-react -- npm run build",
"ci:build:editor": "lerna exec --scope fluxscape-editor -- npm run ci:build", "ci:build:editor": "lerna exec --scope noodl-editor -- npm run ci:build",
"build:editor": "ts-node ./scripts/build-editor.ts", "build:editor": "ts-node ./scripts/build-editor.ts",
"build:editor:_viewer": "ts-node ./scripts/noodl-editor/build-viewer.ts", "build:editor:_viewer": "ts-node ./scripts/noodl-editor/build-viewer.ts",
"build:editor:_editor": "ts-node ./scripts/noodl-editor/build-editor.ts", "build:editor:_editor": "ts-node ./scripts/noodl-editor/build-editor.ts",
@@ -20,7 +20,7 @@
"build:cloud-runtime": "lerna run build --scope @noodl/cloud-runtime --stream && lerna run build:pack --scope @noodl/cloud-runtime --stream", "build:cloud-runtime": "lerna run build --scope @noodl/cloud-runtime --stream && lerna run build:pack --scope @noodl/cloud-runtime --stream",
"start:storybook": "lerna exec --scope @noodl/noodl-core-ui -- npm run start", "start:storybook": "lerna exec --scope @noodl/noodl-core-ui -- npm run start",
"start:viewer": "lerna run start --scope @noodl/noodl-viewer-react --stream", "start:viewer": "lerna run start --scope @noodl/noodl-viewer-react --stream",
"start:editor": "lerna run start --scope fluxscape-editor --stream", "start:editor": "lerna run start --scope noodl-editor --stream",
"dev": "ts-node ./scripts/start.ts", "dev": "ts-node ./scripts/start.ts",
"start": "ts-node ./scripts/start.ts -- --build-viewer", "start": "ts-node ./scripts/start.ts -- --build-viewer",
"test:editor": "ts-node ./scripts/test-editor.ts", "test:editor": "ts-node ./scripts/test-editor.ts",

View File

@@ -9,11 +9,6 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
&.is-hidden {
visibility: hidden;
pointer-events: none;
}
&.has-backdrop { &.has-backdrop {
background-color: var(--theme-color-bg-1-transparent); background-color: var(--theme-color-bg-1-transparent);
} }

View File

@@ -42,7 +42,6 @@ export interface BaseDialogProps extends UnsafeStyleProps {
isVisible?: boolean; isVisible?: boolean;
hasBackdrop?: boolean; hasBackdrop?: boolean;
hasArrow?: boolean; hasArrow?: boolean;
alwaysMounted?: boolean;
children?: Slot; children?: Slot;
@@ -70,7 +69,6 @@ export function CoreBaseDialog({
isVisible, isVisible,
hasBackdrop, hasBackdrop,
hasArrow, hasArrow,
alwaysMounted,
children, children,
@@ -263,7 +261,7 @@ export function CoreBaseDialog({
} }
}, [background]); }, [background]);
if (!isVisible && !alwaysMounted) return null; if (!isVisible) return null;
return ( return (
<div <div
@@ -272,7 +270,6 @@ export function CoreBaseDialog({
hasBackdrop && css['has-backdrop'], hasBackdrop && css['has-backdrop'],
isLockingScroll && css['is-locking-scroll'], isLockingScroll && css['is-locking-scroll'],
typeof triggerRef === 'undefined' && css['is-centered'], typeof triggerRef === 'undefined' && css['is-centered'],
!isVisible && css['is-hidden'],
css[variant] css[variant]
)} )}
onClick={onClose} onClick={onClose}

View File

@@ -11,7 +11,7 @@ import css from './Tooltip.module.scss';
export interface TooltipProps extends UnsafeStyleProps { export interface TooltipProps extends UnsafeStyleProps {
content: SingleSlot; content: SingleSlot;
fineType?: string | string[]; fineType?: string;
children: Slot; children: Slot;
showAfterMs?: number; showAfterMs?: number;
@@ -79,17 +79,9 @@ export function Tooltip({
{fineType && ( {fineType && (
<div className={css['FineType']}> <div className={css['FineType']}>
{Array.isArray(fineType) ? ( <Label size={LabelSize.Small} variant={TextType.Secondary}>
fineType.map((x) => ( {fineType}
<Label size={LabelSize.Small} variant={TextType.Secondary}> </Label>
{x}
</Label>
))
) : (
<Label size={LabelSize.Small} variant={TextType.Secondary}>
{fineType}
</Label>
)}
</div> </div>
)} )}
</BaseDialog> </BaseDialog>

View File

@@ -1,10 +1,10 @@
{ {
"name": "fluxscape-editor", "name": "noodl-editor",
"productName": "Fluxscape", "productName": "Fluxscape",
"description": "Node-Based App Builder for Scalability & Rapid Development, a fork of Noodl", "description": "Node-Based App Builder for Scalability & Rapid Development, a fork of Noodl",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://fluxscape.io", "homepage": "https://fluxscape.io",
"version": "1.1.0", "version": "1.0.0",
"main": "src/main/main.js", "main": "src/main/main.js",
"scripts": { "scripts": {
"build": "npx ts-node -P ./tsconfig.build.json ./scripts/build.ts", "build": "npx ts-node -P ./tsconfig.build.json ./scripts/build.ts",
@@ -58,7 +58,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@electron/remote": "^2.1.2", "@electron/remote": "^2.1.1",
"@jaames/iro": "^5.5.2", "@jaames/iro": "^5.5.2",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@noodl/git": "file:../noodl-git", "@noodl/git": "file:../noodl-git",
@@ -114,7 +114,7 @@
"babel-loader": "^8.2.4", "babel-loader": "^8.2.4",
"concurrently": "^7.4.0", "concurrently": "^7.4.0",
"css-loader": "^6.7.1", "css-loader": "^6.7.1",
"electron": "31.3.1", "electron": "28.1.4",
"electron-builder": "^24.9.1", "electron-builder": "^24.9.1",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"html-loader": "^3.1.0", "html-loader": "^3.1.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95C8.08 7.14 9.94 6 12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11c1.56.1 2.78 1.41 2.78 2.96 0 1.65-1.35 3-3 3zm-9-3.82l-2.09-2.09L6.5 13.5 10 17l6.01-6.01-1.41-1.41z"/></svg>

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none"><path d="M0 0h24v24H0V0z"/><path opacity=".87" d="M0 0h24v24H0V0z"/></g><path d="M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3zM23 3.01H1V9h2V4.99h18v14.03H3V15H1v5.99h22V3.01zM11 16l4-4-4-4v3H1v2h10v3z"/></svg>

After

Width:  |  Height:  |  Size: 408 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 6H2v16h16v-2H4V6zm18-4H6v16h16V2zm-3 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z"/></svg>

After

Width:  |  Height:  |  Size: 220 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none"><path d="M0 0h24v24H0V0z"/><path opacity=".87" d="M0 0h24v24H0V0z"/></g><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7zm-4 6h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></svg>

After

Width:  |  Height:  |  Size: 360 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M19.44 12.99l-.01.02c.04-.33.08-.67.08-1.01 0-.34-.03-.66-.07-.99l.01.02 2.44-1.92-2.43-4.22-2.87 1.16.01.01c-.52-.4-1.09-.74-1.71-1h.01L14.44 2H9.57l-.44 3.07h.01c-.62.26-1.19.6-1.71 1l.01-.01-2.88-1.17-2.44 4.22 2.44 1.92.01-.02c-.04.33-.07.65-.07.99 0 .34.03.68.08 1.01l-.01-.02-2.1 1.65-.33.26 2.43 4.2 2.88-1.15-.02-.04c.53.41 1.1.75 1.73 1.01h-.03L9.58 22h4.85s.03-.18.06-.42l.38-2.65h-.01c.62-.26 1.2-.6 1.73-1.01l-.02.04 2.88 1.15 2.43-4.2s-.14-.12-.33-.26l-2.11-1.66zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></svg>

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Fluxscape</title> <title>Noodl</title>
<link href="../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet" /> <link href="../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="../assets/css/style.css" rel="stylesheet" /> <link href="../assets/css/style.css" rel="stylesheet" />

View File

@@ -2,11 +2,6 @@ import { Keybinding } from '@noodl-utils/keyboard/Keybinding';
import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode'; import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode';
export namespace Keybindings { export namespace Keybindings {
export const SEARCH = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_F);
export const CLOUD_SERVICE_OPEN_DASHBOARD = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_P);
export const CLOUD_SERVICE_OPEN_DASHBOARD_BROWSER = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_P);
export const REFRESH_PREVIEW = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_R); export const REFRESH_PREVIEW = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_R);
export const OPEN_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_D); export const OPEN_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_D);
export const OPEN_CLOUD_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_R); export const OPEN_CLOUD_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_R);

View File

@@ -1,6 +1,7 @@
import { AppRegistry } from '@noodl-models/app_registry'; import { AppRegistry } from '@noodl-models/app_registry';
import { SidebarModel } from '@noodl-models/sidebar'; import { SidebarModel } from '@noodl-models/sidebar';
import { Keybindings } from '@noodl-constants/Keybindings'; import { Keybinding } from '@noodl-utils/keyboard/Keybinding';
import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode';
import { IconName } from '@noodl-core-ui/components/common/Icon'; import { IconName } from '@noodl-core-ui/components/common/Icon';
@@ -68,7 +69,7 @@ export function installSidePanel({ isLesson }: SetupEditorOptions) {
SidebarModel.instance.register({ SidebarModel.instance.register({
id: 'search', id: 'search',
name: 'Search', name: 'Search',
fineType: Keybindings.SEARCH.label, fineType: new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_F).label,
order: 2, order: 2,
icon: IconName.Search, icon: IconName.Search,
panel: SearchPanel panel: SearchPanel

View File

@@ -16,7 +16,6 @@ import { projectFromDirectory, unzipIntoDirectory } from '../models/projectmodel
import FileSystem from './filesystem'; import FileSystem from './filesystem';
import { tracker } from './tracker'; import { tracker } from './tracker';
import { guid } from './utils'; import { guid } from './utils';
import { getTopLevelWorkingDirectory } from '@noodl/git/src/core/open';
export interface ProjectItem { export interface ProjectItem {
id: string; id: string;
@@ -268,15 +267,12 @@ export class LocalProjectsModel extends Model {
}); });
} }
/** isGitProject(project: ProjectModel): boolean {
* Check if this project is in a git repository. // TODO: check if there's is git in any parent folder too
*
* @param project // Check if the git folder exists.
* @returns const gitPath = filesystem.join(project._retainedProjectDirectory, '.git');
*/ return filesystem.exists(gitPath);
async isGitProject(project: ProjectModel): Promise<boolean> {
const gitPath = await getTopLevelWorkingDirectory(project._retainedProjectDirectory);
return gitPath !== null;
} }
setCurrentGlobalGitAuth(projectId: string) { setCurrentGlobalGitAuth(projectId: string) {

View File

@@ -41,7 +41,7 @@ export class HtmlProcessor {
baseUrl = baseUrl + '/'; baseUrl = baseUrl + '/';
} }
const title = parameters.title || settings.htmlTitle || 'Fluxscape Viewer'; const title = parameters.title || settings.htmlTitle || 'Noodl Viewer';
let headCode = settings.headCode || ''; let headCode = settings.headCode || '';
if (parameters.headCode) { if (parameters.headCode) {

View File

@@ -6,7 +6,7 @@ import { ITemplateProvider, ProgressCallback, TemplateItem, TemplateListFilter }
*/ */
export class NoodlDocsTemplateProvider implements ITemplateProvider { export class NoodlDocsTemplateProvider implements ITemplateProvider {
get name(): string { get name(): string {
return this.getDocsEndpoint() || 'https://docs.fluxscape.io'; return 'https://docs.noodl.net';
} }
constructor(private readonly getDocsEndpoint: () => string) {} constructor(private readonly getDocsEndpoint: () => string) {}

View File

@@ -11,14 +11,6 @@ export interface ArrayDiff<T> {
changed: T[]; changed: T[];
unchanged: T[]; unchanged: T[];
} }
export function createEmptyArrayDiff<T>(): ArrayDiff<T> {
return {
deleted: [],
created: [],
changed: [],
unchanged: [],
}
}
export interface ProjectDiffItem { export interface ProjectDiffItem {
graph: TSFixme; graph: TSFixme;

View File

@@ -13,7 +13,6 @@ export default class SchemaHandler {
public dbCollections: TSFixme[]; public dbCollections: TSFixme[];
public systemCollections: TSFixme[]; public systemCollections: TSFixme[];
public configSchema: TSFixme; public configSchema: TSFixme;
public parseServerVersion: string;
constructor() { constructor() {
EventDispatcher.instance.on( EventDispatcher.instance.on(
@@ -120,20 +119,6 @@ export default class SchemaHandler {
console.log(e); console.log(e);
} }
}); });
// Get Parse Server Version & Supported features
fetch(environment.url + '/serverInfo', {
method: 'POST',
body: JSON.stringify({
"_method": "GET",
"_ApplicationId": environment.appId,
"_MasterKey": environment.masterKey,
})
})
.then((response) => response.json())
.then((json) => {
this.parseServerVersion = json.parseServerVersion;
});
}); });
}); });
} }
@@ -144,20 +129,10 @@ export default class SchemaHandler {
ProjectModel.instance.setMetaData('dbCollections', this.dbCollections); ProjectModel.instance.setMetaData('dbCollections', this.dbCollections);
ProjectModel.instance.setMetaData('systemCollections', this.systemCollections); ProjectModel.instance.setMetaData('systemCollections', this.systemCollections);
ProjectModel.instance.setMetaData('dbConfigSchema', this.configSchema); ProjectModel.instance.setMetaData('dbConfigSchema', this.configSchema);
const versionNumbers = this.parseServerVersion?.split(".")
if (versionNumbers && versionNumbers.length > 0) {
// Let's only save the major version number,
// since this will be used to determine which verison of the API to use.
ProjectModel.instance.setMetaData('dbVersionMajor', versionNumbers[0]);
} else {
ProjectModel.instance.setMetaData('dbVersionMajor', undefined);
}
} else { } else {
ProjectModel.instance.setMetaData('dbCollections', undefined); ProjectModel.instance.setMetaData('dbCollections', undefined);
ProjectModel.instance.setMetaData('systemCollections', undefined); ProjectModel.instance.setMetaData('systemCollections', undefined);
ProjectModel.instance.setMetaData('dbConfigSchema', undefined); ProjectModel.instance.setMetaData('dbConfigSchema', undefined);
ProjectModel.instance.setMetaData('dbVersionMajor', undefined);
} }
} }
} }

View File

@@ -1,6 +1,5 @@
import React, { RefObject } from 'react'; import { usePluginContext } from '@noodl-contexts/PluginContext';
import React, { RefObject, useEffect, useRef } from 'react';
import { ProjectModel } from '@noodl-models/projectmodel';
import { ActivityIndicator } from '@noodl-core-ui/components/common/ActivityIndicator'; import { ActivityIndicator } from '@noodl-core-ui/components/common/ActivityIndicator';
import { BaseDialog } from '@noodl-core-ui/components/layout/BaseDialog'; import { BaseDialog } from '@noodl-core-ui/components/layout/BaseDialog';
@@ -55,7 +54,6 @@ export function DeployPopup(props: DeployPopupProps) {
onClose={props.onClose} onClose={props.onClose}
hasArrow hasArrow
isLockingScroll isLockingScroll
alwaysMounted
> >
<DeployPopupChild /> <DeployPopupChild />
</BaseDialog> </BaseDialog>
@@ -64,19 +62,6 @@ export function DeployPopup(props: DeployPopupProps) {
} }
function FluxscapeDeployTab() { function FluxscapeDeployTab() {
const params = {}; // Preview URL: 'http://192.168.0.33:8574/'
return <iframe src="https://portal.fluxscape.io" style={{ width: "100%", height: "50vh", borderStyle: "none" }} />;
const projectId = ProjectModel.instance.id;
if (projectId) {
params['projectId'] = projectId;
}
const urlParams = new URLSearchParams(params);
return (
<iframe
src={`https://portal.fluxscape.io/?${urlParams.toString()}`}
style={{ width: '100%', height: '50vh', borderStyle: 'none' }}
/>
);
} }

View File

@@ -1,16 +1,13 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Keybindings } from '@noodl-constants/Keybindings';
import { Environment } from '@noodl-models/CloudServices'; import { Environment } from '@noodl-models/CloudServices';
import ParseDashboardServer from '@noodl-utils/parsedashboardserver'; import ParseDashboardServer from '@noodl-utils/parsedashboardserver';
import { Icon, IconName, IconSize } from '@noodl-core-ui/components/common/Icon'; import { Icon, IconName, IconSize } from '@noodl-core-ui/components/common/Icon';
import { IconButton, IconButtonState, IconButtonVariant } from '@noodl-core-ui/components/inputs/IconButton'; import { IconButton, IconButtonState, IconButtonVariant } from '@noodl-core-ui/components/inputs/IconButton';
import { PrimaryButton, PrimaryButtonSize, PrimaryButtonVariant } from '@noodl-core-ui/components/inputs/PrimaryButton'; import { PrimaryButton, PrimaryButtonSize, PrimaryButtonVariant } from '@noodl-core-ui/components/inputs/PrimaryButton';
import { DialogRenderDirection } from '@noodl-core-ui/components/layout/BaseDialog';
import { Collapsible } from '@noodl-core-ui/components/layout/Collapsible'; import { Collapsible } from '@noodl-core-ui/components/layout/Collapsible';
import { Tooltip } from '@noodl-core-ui/components/popups/Tooltip';
import { Label, LabelSpacingSize } from '@noodl-core-ui/components/typography/Label'; import { Label, LabelSpacingSize } from '@noodl-core-ui/components/typography/Label';
import { Text, TextType } from '@noodl-core-ui/components/typography/Text'; import { Text, TextType } from '@noodl-core-ui/components/typography/Text';
@@ -121,21 +118,12 @@ export function CloudServiceCard({
</div> </div>
{isEditorEnvironment && ( {isEditorEnvironment && (
<Tooltip <PrimaryButton
content="Open the Parse Dashboard" label="Open dashboard"
fineType={[ size={PrimaryButtonSize.Small}
`In Window: ${Keybindings.CLOUD_SERVICE_OPEN_DASHBOARD.label}`, onClick={onDashboardClicked}
`In Browser: ${Keybindings.CLOUD_SERVICE_OPEN_DASHBOARD_BROWSER.label}` isGrowing
]} />
renderDirection={DialogRenderDirection.Below}
>
<PrimaryButton
label="Open dashboard"
size={PrimaryButtonSize.Small}
onClick={onDashboardClicked}
isGrowing
/>
</Tooltip>
)} )}
</div> </div>
</div> </div>

View File

@@ -199,7 +199,6 @@ function BaseVersionControlPanel() {
export function VersionControlPanel() { export function VersionControlPanel() {
const [git, setGit] = useState<Git>(null); const [git, setGit] = useState<Git>(null);
const [state, setState] = useState<'loading' | 'loaded' | 'not-git'>('loading');
async function createGit() { async function createGit() {
const gitClient = new Git(mergeProject); const gitClient = new Git(mergeProject);
@@ -207,18 +206,12 @@ export function VersionControlPanel() {
setGit(gitClient); setGit(gitClient);
} }
const isGitProject = git === null ? LocalProjectsModel.instance.isGitProject(ProjectModel.instance) : true;
useEffect(() => { useEffect(() => {
LocalProjectsModel.instance if (isGitProject) {
.isGitProject(ProjectModel.instance) createGit();
.then(async (isGitProject) => { }
if (isGitProject) { }, [isGitProject]);
await createGit();
setState('loaded');
} else {
setState('not-git');
}
});
}, []);
async function setupGit() { async function setupGit() {
const gitClient = new Git(mergeProject); const gitClient = new Git(mergeProject);
@@ -227,7 +220,7 @@ export function VersionControlPanel() {
setGit(gitClient); setGit(gitClient);
} }
if (git === null && state === 'not-git') { if (git === null && !isGitProject) {
return ( return (
<BasePanel isFill title="Version Control"> <BasePanel isFill title="Version Control">
<Box hasXSpacing hasYSpacing> <Box hasXSpacing hasYSpacing>

View File

@@ -6,13 +6,11 @@ import { Commit } from '@noodl/git/src/core/models/snapshot';
import { FileChange } from '@noodl/git/src/core/models/status'; import { FileChange } from '@noodl/git/src/core/models/status';
import { revRange } from '@noodl/git/src/core/rev-list'; import { revRange } from '@noodl/git/src/core/rev-list';
import { ProjectModel } from '@noodl-models/projectmodel';
import { applyPatches } from '@noodl-models/ProjectPatches/applypatches'; import { applyPatches } from '@noodl-models/ProjectPatches/applypatches';
import { mergeProject } from '@noodl-utils/projectmerger'; import { mergeProject } from '@noodl-utils/projectmerger';
import { ProjectDiff, diffProject } from '@noodl-utils/projectmerger.diff'; import { ProjectDiff, diffProject } from '@noodl-utils/projectmerger.diff';
import { useVersionControlContext } from '../context'; import { useVersionControlContext } from '../context';
import { getProjectFilePath } from '../context/DiffUtils';
import { DiffList } from './DiffList'; import { DiffList } from './DiffList';
//Kind: //Kind:
@@ -126,10 +124,7 @@ async function getMergeDiff(repositoryPath: string, commit: Commit, refToDiffTo:
} }
async function getProjectFile(commit: Commit) { async function getProjectFile(commit: Commit) {
const projectFilePath = getProjectFilePath(commit.repositoryDir, ProjectModel.instance._retainedProjectDirectory); const projectContent = JSON.parse(await commit.getFileAsString('project.json'));
const projectContentRaw = await commit.getFileAsString(projectFilePath);
const projectContent = JSON.parse(projectContentRaw);
applyPatches(projectContent); applyPatches(projectContent);
return projectContent; return projectContent;
} }

View File

@@ -61,7 +61,7 @@ export function DiffList({ diff, fileChanges, componentDiffTitle, actions, commi
const [imageDiff, setImageDiff] = useState<IImageDiff>(null); const [imageDiff, setImageDiff] = useState<IImageDiff>(null);
const components = diff?.components ? getChangedComponents(diff.components) : []; const components = diff?.components ? getChangedComponents(diff.components) : [];
const files = (fileChanges || [])?.filter((f) => !f.path.endsWith('project.json')) || []; const files = (fileChanges || [])?.filter((f) => f.path !== 'project.json') || [];
const settings = diff?.settings ? getChangedObjectProperties(diff.settings) : []; const settings = diff?.settings ? getChangedObjectProperties(diff.settings) : [];
const colorStyles = diff?.styles.colors ? getChangedObjectProperties(diff.styles.colors) : []; const colorStyles = diff?.styles.colors ? getChangedObjectProperties(diff.styles.colors) : [];
const textStyles = diff?.styles.text ? getChangedObjectProperties(diff.styles.text) : []; const textStyles = diff?.styles.text ? getChangedObjectProperties(diff.styles.text) : [];

View File

@@ -1,24 +1,21 @@
import path from 'path';
import { getCommit } from '@noodl/git/src/core/logs';
import { FileStatusKind } from '@noodl/git/src/core/models/status';
import { FeedbackType } from '@noodl-constants/FeedbackType';
import { applyPatches } from '@noodl-models/ProjectPatches/applypatches';
import { import {
ProjectDiff, ProjectDiff,
ProjectDiffItem, ProjectDiffItem,
ProjectBasicDiffItem, ProjectBasicDiffItem,
ArrayDiff, ArrayDiff,
diffProject, diffProject
createEmptyArrayDiff
} from '@noodl-utils/projectmerger.diff'; } from '@noodl-utils/projectmerger.diff';
import { IconName } from '@noodl-core-ui/components/common/Icon';
import { ListItemProps } from '@noodl-core-ui/components/layout/ListItem';
import { ProjectModel } from '../../../../models/projectmodel'; import { ProjectModel } from '../../../../models/projectmodel';
export interface ProjectLocalDiff extends ProjectDiff { import { applyPatches } from '@noodl-models/ProjectPatches/applypatches';
import { FileStatusKind } from '@noodl/git/src/core/models/status';
import { IconName } from '@noodl-core-ui/components/common/Icon';
import { ListItemProps } from '@noodl-core-ui/components/layout/ListItem';
import { FeedbackType } from '@noodl-constants/FeedbackType';
import { getCommit } from '@noodl/git/src/core/logs';
export interface ProjectLocalDiff extends ProjectDiff{
baseProject: TSFixme; //Project model as an object from raw json baseProject: TSFixme; //Project model as an object from raw json
commitShaDiffedTo: string; commitShaDiffedTo: string;
} }
@@ -87,49 +84,17 @@ export function getFileStatusIconProps(status: FileStatusKind): Partial<ListItem
} }
} }
export function getProjectFilePath(repositoryPath: string, projectPath: string) { export async function doLocalDiff(repositoryPath: string, headCommitId: string): Promise<ProjectLocalDiff> {
const relativePath = path.relative(repositoryPath, projectPath); const baseCommit = await getCommit(repositoryPath, headCommitId);
const projectFilePath = path.join(relativePath, 'project.json').replaceAll('\\', '/'); const baseProjectJson = await baseCommit.getFileAsString('project.json');
return projectFilePath; const baseProject = JSON.parse(baseProjectJson);
} applyPatches(baseProject);
export async function doLocalDiff( const diff = diffProject(baseProject, ProjectModel.instance.toJSON());
repositoryPath: string,
projectPath: string, return {
headCommitId: string ...diff,
): Promise<ProjectLocalDiff> { baseProject,
const projectFilePath = getProjectFilePath(repositoryPath, projectPath); commitShaDiffedTo: headCommitId
};
try {
const baseCommit = await getCommit(projectPath, headCommitId);
const baseProjectJson = await baseCommit.getFileAsString(projectFilePath);
const baseProject = JSON.parse(baseProjectJson);
applyPatches(baseProject);
const diff = diffProject(baseProject, ProjectModel.instance.toJSON());
return {
...diff,
baseProject,
commitShaDiffedTo: headCommitId
};
} catch (error) {
if (error.toString().includes('exists on disk, but not in')) {
console.warn('project.json does not exist in this commit.');
}
// Return empty state
return {
baseProject: {},
commitShaDiffedTo: headCommitId,
components: createEmptyArrayDiff(),
variants: createEmptyArrayDiff(),
settings: createEmptyArrayDiff(),
styles: {
colors: createEmptyArrayDiff(),
text: createEmptyArrayDiff()
},
cloudservices: createEmptyArrayDiff()
};
}
} }

View File

@@ -8,7 +8,6 @@ import { Slot } from '@noodl-core-ui/types/global';
import { doLocalDiff, ProjectLocalDiff } from './DiffUtils'; import { doLocalDiff, ProjectLocalDiff } from './DiffUtils';
import { useVersionControlFetch } from './fetch.context'; import { useVersionControlFetch } from './fetch.context';
import { BranchStatus, IVersionControlContext } from './types'; import { BranchStatus, IVersionControlContext } from './types';
import { ProjectModel } from '@noodl-models/projectmodel';
const VersionControlContext = createContext<IVersionControlContext>({ const VersionControlContext = createContext<IVersionControlContext>({
git: null, git: null,
@@ -58,8 +57,7 @@ export function VersionControlProvider({ git, children }: { git: Git; children:
(async () => { (async () => {
const currentCommitSha = await git.getHeadCommitId(); const currentCommitSha = await git.getHeadCommitId();
if (currentCommitSha) { if (currentCommitSha) {
const projectPath = ProjectModel.instance._retainedProjectDirectory; const diff = await doLocalDiff(git.repositoryPath, currentCommitSha);
const diff = await doLocalDiff(git.repositoryPath, projectPath, currentCommitSha);
setLocalDiff(diff); setLocalDiff(diff);
} }
})(); })();

View File

@@ -5,8 +5,6 @@ import { useSidePanelKeyboardCommands } from '@noodl-hooks/useKeyboardCommands';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { ComponentModel } from '@noodl-models/componentmodel';
import { NodeGraphNode } from '@noodl-models/nodegraphmodel';
import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode'; import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode';
import { performSearch } from '@noodl-utils/universal-search'; import { performSearch } from '@noodl-utils/universal-search';
@@ -56,7 +54,7 @@ export function SearchPanel() {
} }
}, [debouncedSearchTerm]); }, [debouncedSearchTerm]);
function onSearchItemClicked(searchResult: SearchResultItem) { function onSearchItemClicked(searchResult) {
if (searchResult.type === 'Component') { if (searchResult.type === 'Component') {
NodeGraphContextTmp.switchToComponent(searchResult.componentTarget, { NodeGraphContextTmp.switchToComponent(searchResult.componentTarget, {
breadcrumbs: false, breadcrumbs: false,
@@ -87,7 +85,29 @@ export function SearchPanel() {
<div className={css.SearchResults}> <div className={css.SearchResults}>
{searchResults.map((component) => ( {searchResults.map((component) => (
<SearchItem key={component.componentId} component={component} onSearchItemClicked={onSearchItemClicked} /> <Section
title={`${component.componentName} (${component.results.length} result${
component.results.length > 1 ? 's' : ''
})`}
key={component.componentId}
variant={SectionVariant.Panel}
>
{component.results.map((result, index) => (
<div
className={classNames(
css.SearchResultItem
// lastActiveComponentId === result.componentTarget.id && css['is-active']
)}
key={index}
onClick={() => onSearchItemClicked(result)}
>
<Label variant={TextType.Proud}>
{result.userLabel ? result.type + ' - ' + result.userLabel : result.type}
</Label>
<Text>{result.label}</Text>
</div>
))}
</Section>
))} ))}
{searchResults.length === 0 && debouncedSearchTerm.length > 0 && ( {searchResults.length === 0 && debouncedSearchTerm.length > 0 && (
<Container hasXSpacing hasYSpacing> <Container hasXSpacing hasYSpacing>
@@ -98,51 +118,3 @@ export function SearchPanel() {
</BasePanel> </BasePanel>
); );
} }
type SearchResultItem = {
componentTarget: ComponentModel;
label: string;
nodeTarget: NodeGraphNode;
type: string;
userLabel: string;
};
type SearchItemProps = {
component: {
componentName: string;
componentId: string;
results: SearchResultItem[];
};
onSearchItemClicked: (item: SearchResultItem) => void;
};
function SearchItem({ component, onSearchItemClicked }: SearchItemProps) {
const resultCountText = `${component.results.length} result${component.results.length > 1 ? 's' : ''}`;
let titleText = `${component.componentName} (${resultCountText})`;
// We expect there to always be at least one result, to get the full component name.
const isInCloudFunctions = component.results[0].componentTarget.name.startsWith('/#__cloud__/');
if (isInCloudFunctions) {
titleText += ' (Cloud Function)';
}
return (
<Section title={titleText} variant={SectionVariant.Panel}>
{component.results.map((result, index) => (
<div
className={classNames(
css.SearchResultItem
// lastActiveComponentId === result.componentTarget.id && css['is-active']
)}
key={index}
onClick={() => onSearchItemClicked(result)}
>
<Label variant={TextType.Proud}>
{result.userLabel ? result.type + ' - ' + result.userLabel : result.type}
</Label>
<Text>{result.label}</Text>
</div>
))}
</Section>
);
}

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Fluxscape Viewer</title> <title>Noodl Viewer</title>
<link href="../../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet"> <link href="../../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet">
<link href="assets/style.css" rel="stylesheet"> <link href="assets/style.css" rel="stylesheet">
<script type="text/javascript" src="../../assets/lib/jquery-min.js"></script> <script type="text/javascript" src="../../assets/lib/jquery-min.js"></script>

View File

@@ -67,7 +67,7 @@ function startServer(app, projectGetSettings, projectGetInfo, projectGetComponen
ProjectModules.instance.injectIntoHtml(info.projectDirectory, data, '/', function (injected) { ProjectModules.instance.injectIntoHtml(info.projectDirectory, data, '/', function (injected) {
projectGetSettings((settings) => { projectGetSettings((settings) => {
settings = settings || {}; settings = settings || {};
injected = injected.replace('{{#title#}}', settings.htmlTitle || 'Fluxscape Viewer'); injected = injected.replace('{{#title#}}', settings.htmlTitle || 'Noodl Viewer');
injected = injected.replace('{{#customHeadCode#}}', settings.headCode || ''); injected = injected.replace('{{#customHeadCode#}}', settings.headCode || '');
response.writeHead(200, { response.writeHead(200, {

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "", "description": "",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io", "homepage": "https://noodl.net",
"dependencies": { "dependencies": {
"desktop-trampoline": "https://github.com/desktop/desktop-trampoline/archive/refs/tags/v0.9.8.tar.gz", "desktop-trampoline": "https://github.com/desktop/desktop-trampoline/archive/refs/tags/v0.9.8.tar.gz",
"dugite": "^1.106.0", "dugite": "^1.106.0",

View File

@@ -22,11 +22,7 @@ export async function open(basePath: string): Promise<string> {
// console.log("VCS error when opening project: " + e); // console.log("VCS error when opening project: " + e);
// } // }
return basePath;
// Find the relative git repository path
const repositoryPath = await getTopLevelWorkingDirectory(basePath);
return repositoryPath;
} }
/** /**

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io", "homepage": "https://noodl.net",
"dependencies": { "dependencies": {
"@noodl/platform": "file:../noodl-platform", "@noodl/platform": "file:../noodl-platform",
"@noodl/platform-node": "file:../noodl-platform-node" "@noodl/platform-node": "file:../noodl-platform-node"

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io", "homepage": "https://noodl.net",
"scripts": { "scripts": {
"test": "jest", "test": "jest",
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage"

View File

@@ -3,6 +3,6 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io" "homepage": "https://noodl.net"
} }

View File

@@ -32,15 +32,12 @@ class CloudStore {
_initCloudServices() { _initCloudServices() {
_collections = undefined; // clear collection cache, so it's refetched _collections = undefined; // clear collection cache, so it's refetched
const cloudServices = NoodlRuntime.instance.getMetaData('cloudservices'); const cloudServices = NoodlRuntime.instance.getMetaData('cloudservices');
if (cloudServices) { if (cloudServices) {
this.appId = cloudServices.appId; this.appId = cloudServices.appId;
this.endpoint = cloudServices.endpoint; this.endpoint = cloudServices.endpoint;
} }
const dbVersionMajor = NoodlRuntime.instance.getMetaData('dbVersionMajor');
this.dbVersionMajor = dbVersionMajor;
} }
on() { on() {
@@ -171,10 +168,13 @@ class CloudStore {
return; return;
} }
if (options.where) args.push('match=' + encodeURIComponent(JSON.stringify(options.where)));
if (options.limit) args.push('limit=' + options.limit); if (options.limit) args.push('limit=' + options.limit);
if (options.skip) args.push('skip=' + options.skip); if (options.skip) args.push('skip=' + options.skip);
const grouping = {}; const grouping = {
objectId: null
};
Object.keys(options.group).forEach((k) => { Object.keys(options.group).forEach((k) => {
const _g = {}; const _g = {};
@@ -188,20 +188,7 @@ class CloudStore {
grouping[k] = _g; grouping[k] = _g;
}); });
// I don't know which version the API was changed, lets just say above 4 for now. args.push('group=' + JSON.stringify(grouping));
if (this.dbVersionMajor && this.dbVersionMajor > 4) {
grouping._id = null;
if (options.where) args.push('$match=' + encodeURIComponent(JSON.stringify(options.where)));
args.push('$group=' + JSON.stringify(grouping));
} else {
grouping.objectId = null;
if (options.where) args.push('match=' + encodeURIComponent(JSON.stringify(options.where)));
args.push('group=' + JSON.stringify(grouping));
}
this._makeRequest('/aggregate/' + options.collection + (args.length > 0 ? '?' + args.join('&') : ''), { this._makeRequest('/aggregate/' + options.collection + (args.length > 0 ? '?' + args.join('&') : ''), {
success: function (response) { success: function (response) {

View File

@@ -12,7 +12,6 @@ function createRecordsAPI(modelScope) {
return { return {
async query(className, query, options) { async query(className, query, options) {
if (typeof className === "undefined") throw new Error("'className' is undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cloudstore().query({ cloudstore().query({
collection: className, collection: className,
@@ -40,7 +39,6 @@ function createRecordsAPI(modelScope) {
}, },
async count(className, query) { async count(className, query) {
if (typeof className === "undefined") throw new Error("'className' is undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cloudstore().count({ cloudstore().count({
collection: className, collection: className,
@@ -62,7 +60,6 @@ function createRecordsAPI(modelScope) {
}, },
async distinct(className, property, query) { async distinct(className, property, query) {
if (typeof className === "undefined") throw new Error("'className' is undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cloudstore().distinct({ cloudstore().distinct({
collection: className, collection: className,
@@ -85,7 +82,6 @@ function createRecordsAPI(modelScope) {
}, },
async aggregate(className, group, query) { async aggregate(className, group, query) {
if (typeof className === "undefined") throw new Error("'className' is undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cloudstore().aggregate({ cloudstore().aggregate({
collection: className, collection: className,
@@ -108,7 +104,6 @@ function createRecordsAPI(modelScope) {
}, },
async fetch(objectOrId, options) { async fetch(objectOrId, options) {
if (typeof objectOrId === 'undefined') return Promise.reject(new Error("'objectOrId' is undefined."));
if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId(); if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId();
const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class; const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class;
@@ -131,7 +126,6 @@ function createRecordsAPI(modelScope) {
}, },
async increment(objectOrId, properties, options) { async increment(objectOrId, properties, options) {
if (typeof objectOrId === 'undefined') return Promise.reject(new Error("'objectOrId' is undefined."));
if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId(); if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId();
const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class; const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class;
@@ -155,7 +149,6 @@ function createRecordsAPI(modelScope) {
}, },
async save(objectOrId, properties, options) { async save(objectOrId, properties, options) {
if (typeof objectOrId === 'undefined') return Promise.reject(new Error("'objectOrId' is undefined."));
if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId(); if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId();
const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class; const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class;
@@ -186,7 +179,6 @@ function createRecordsAPI(modelScope) {
}, },
async create(className, properties, options) { async create(className, properties, options) {
if (typeof className === "undefined") throw new Error("'className' is undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cloudstore().create({ cloudstore().create({
collection: className, collection: className,
@@ -205,7 +197,6 @@ function createRecordsAPI(modelScope) {
}, },
async delete(objectOrId, options) { async delete(objectOrId, options) {
if (typeof objectOrId === 'undefined') return Promise.reject(new Error("'objectOrId' is undefined."));
if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId(); if (typeof objectOrId !== 'string') objectOrId = objectOrId.getId();
const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class; const className = (options ? options.className : undefined) || (modelScope || Model).get(objectOrId)._class;
@@ -274,7 +265,7 @@ function createRecordsAPI(modelScope) {
resolve(); resolve();
}, },
error: (err) => { error: (err) => {
reject(Error(err || 'Failed to add relation.')); reject(Error(rr || 'Failed to add relation.'));
} }
}); });
}); });

View File

@@ -75,10 +75,10 @@ var SetDbModelPropertiedNodeDefinition = {
_this.setError('Missing Record Id'); _this.setError('Missing Record Id');
return; return;
} }
var model = internal.model;
const model = internal.model; for (var i in internal.inputValues) {
for (const key in internal.inputValues) { model.set(i, internal.inputValues[i], { resolve: true });
model.set(key, internal.inputValues[key], { resolve: true });
} }
CloudStore.forScope(_this.nodeScope.modelScope).save({ CloudStore.forScope(_this.nodeScope.modelScope).save({

View File

@@ -59,7 +59,6 @@ const DateToStringNode = {
const month = ('0' + (t.getMonth() + 1)).slice(-2); const month = ('0' + (t.getMonth() + 1)).slice(-2);
const monthShort = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(t); const monthShort = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(t);
const year = t.getFullYear(); const year = t.getFullYear();
const yearShort = year.toString().substring(2);
const hours = ('0' + t.getHours()).slice(-2); const hours = ('0' + t.getHours()).slice(-2);
const minutes = ('0' + t.getMinutes()).slice(-2); const minutes = ('0' + t.getMinutes()).slice(-2);
const seconds = ('0' + t.getSeconds()).slice(-2); const seconds = ('0' + t.getSeconds()).slice(-2);
@@ -69,7 +68,6 @@ const DateToStringNode = {
.replace(/\{month\}/g, month) .replace(/\{month\}/g, month)
.replace(/\{monthShort\}/g, monthShort) .replace(/\{monthShort\}/g, monthShort)
.replace(/\{year\}/g, year) .replace(/\{year\}/g, year)
.replace(/\{yearShort\}/g, yearShort)
.replace(/\{hours\}/g, hours) .replace(/\{hours\}/g, hours)
.replace(/\{minutes\}/g, minutes) .replace(/\{minutes\}/g, minutes)
.replace(/\{seconds\}/g, seconds); .replace(/\{seconds\}/g, seconds);

View File

@@ -2,8 +2,6 @@ const StringFormatDefinition = {
name: 'String Format', name: 'String Format',
docs: 'https://docs.noodl.net/nodes/string-manipulation/string-format', docs: 'https://docs.noodl.net/nodes/string-manipulation/string-format',
category: 'String Manipulation', category: 'String Manipulation',
usePortAsLabel: 'format',
portLabelTruncationMode: 'length',
initialize() { initialize() {
const internal = this._internal; const internal = this._internal;
internal.format = ''; internal.format = '';

View File

@@ -3,6 +3,6 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.d.ts", "main": "src/index.d.ts",
"description": "", "description": "",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io" "homepage": "https://noodl.net"
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "@noodl/cloud-runtime", "name": "@noodl/cloud-runtime",
"author": "Fluxscape <contact@fluxscape.io>", "author": "Noodl <info@noodl.net>",
"homepage": "https://fluxscape.io", "homepage": "https://noodl.net",
"version": "0.6.3", "version": "0.6.3",
"license": "MIT", "license": "MIT",
"main": "dist/main.js", "main": "dist/main.js",

View File

@@ -74,59 +74,6 @@ declare namespace Noodl {
*/ */
const Object: any; const Object: any;
type RecordQuery<T> =
{
lessThan: T
} |
{
lessThanOrEqualTo: T
} |
{
greaterThan: T
} |
{
greaterThanOrEqualTo: T
} |
{
equalTo: T
} |
{
notEqualTo: T
} |
{
containedIn: T
} |
{
notContainedIn : T
} |
{
exists: T
} |
{
matchesRegex: T
} |
{
text: T
} |
{
idEqualTo: T
} |
{
idContainedIn: T
} |
{
pointsTo: T
} |
{
relatedTo: T
};
type RecordQueryField<T> = T extends RecordQuery<any> ?
{ [K in keyof T]: { [P in K]: T[P] } & Partial<Record<Exclude<keyof T, K>, never>> }[keyof T]
: never;
type RecordSortKey<T extends string> = (`${T}` | `-${T}`)[];
interface RecordsApi { interface RecordsApi {
/** /**
* This is an async function that will query the database using the query * This is an async function that will query the database using the query
@@ -168,17 +115,15 @@ declare namespace Noodl {
* }) * })
* ``` * ```
*/ */
query<TClassName extends RecordClassName>( query(
className: TClassName, className: RecordClassName,
query?: query?: any,
RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }> |
{ and: RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }>[] },
options?: { options?: {
limit?: number; limit?: number;
skip?: number; skip?: number;
sort?: string | RecordSortKey<keyof DatabaseSchema[TClassName]>; sort?: string[];
include?: string | (keyof DatabaseSchema[TClassName])[]; include?: any;
select?: string | (keyof DatabaseSchema[TClassName])[]; select?: any;
} }
): Promise<any>; ): Promise<any>;

View File

@@ -8,8 +8,6 @@ export interface ButtonProps extends Noodl.ReactProps {
enabled: boolean; enabled: boolean;
buttonType: 'button' | 'submit'; buttonType: 'button' | 'submit';
attrs: React.Attributes;
textStyle: Noodl.TextStyle; textStyle: Noodl.TextStyle;
useLabel: boolean; useLabel: boolean;
@@ -98,7 +96,6 @@ export function Button(props: ButtonProps) {
return ( return (
<button <button
{...props.attrs}
className={className} className={className}
disabled={!props.enabled} disabled={!props.enabled}
{...Utils.controlEvents(props)} {...Utils.controlEvents(props)}

View File

@@ -9,8 +9,6 @@ export interface CheckboxProps extends Noodl.ReactProps {
enabled: boolean; enabled: boolean;
checked: boolean; checked: boolean;
attrs: React.Attributes;
useLabel: boolean; useLabel: boolean;
label: string; label: string;
labelSpacing: string; labelSpacing: string;
@@ -49,7 +47,6 @@ export function Checkbox(props: CheckboxProps) {
Layout.align(style, props); Layout.align(style, props);
const inputProps = { const inputProps = {
...props.attrs,
id: props.id, id: props.id,
className: [props.className, 'ndl-controls-checkbox-2'].join(' '), className: [props.className, 'ndl-controls-checkbox-2'].join(' '),
disabled: !props.enabled, disabled: !props.enabled,

View File

@@ -10,8 +10,6 @@ export interface RadioButtonProps extends Noodl.ReactProps {
enabled: boolean; enabled: boolean;
value: string; value: string;
attrs: React.Attributes;
useLabel: boolean; useLabel: boolean;
label: string; label: string;
labelSpacing: string; labelSpacing: string;
@@ -49,7 +47,6 @@ export function RadioButton(props: RadioButtonProps) {
props.checkedChanged && props.checkedChanged(radioButtonGroup ? radioButtonGroup.selected === props.value : false); props.checkedChanged && props.checkedChanged(radioButtonGroup ? radioButtonGroup.selected === props.value : false);
const inputProps = { const inputProps = {
...props.attrs,
id: props.id, id: props.id,
disabled: !props.enabled, disabled: !props.enabled,
className: [props.className, 'ndl-controls-radio-2'].join(' '), className: [props.className, 'ndl-controls-radio-2'].join(' '),

View File

@@ -12,8 +12,6 @@ export interface SelectProps extends Noodl.ReactProps {
textStyle: Noodl.TextStyle; textStyle: Noodl.TextStyle;
items: TSFixme; items: TSFixme;
attrs: React.Attributes;
placeholder: string; placeholder: string;
placeholderOpacity: string; placeholderOpacity: string;
@@ -83,7 +81,6 @@ export function Select(props: SelectProps) {
} }
const inputProps = { const inputProps = {
...props.attrs,
id: props.id, id: props.id,
className: props.className, className: props.className,
style: { style: {

View File

@@ -2,15 +2,13 @@ import React, { useEffect, useState } from 'react';
import Layout from '../../../layout'; import Layout from '../../../layout';
import Utils from '../../../nodes/controls/utils'; import Utils from '../../../nodes/controls/utils';
import { Noodl } from '../../../types'; import { Noodl, Slot } from '../../../types';
export interface SliderProps extends Noodl.ReactProps { export interface SliderProps extends Noodl.ReactProps {
_nodeId: string; _nodeId: string;
id: string; id: string;
enabled: boolean; enabled: boolean;
attrs: React.Attributes;
value: number; value: number;
min: number; min: number;
max: number; max: number;
@@ -26,6 +24,8 @@ export interface SliderProps extends Noodl.ReactProps {
onClick: () => void; onClick: () => void;
updateOutputValue: (value: number) => void; updateOutputValue: (value: number) => void;
children: Slot;
} }
function _styleTemplate(_class: string, props: SliderProps) { function _styleTemplate(_class: string, props: SliderProps) {
@@ -105,7 +105,6 @@ export function Slider(props: SliderProps) {
const className = `ndl-controls-range2 ${instanceClassId} ${props.className ? props.className : ''} `; const className = `ndl-controls-range2 ${instanceClassId} ${props.className ? props.className : ''} `;
const inputProps: React.InputHTMLAttributes<HTMLInputElement> = { const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {
...props.attrs,
id: props.id, id: props.id,
style: { style: {
width: '100%', width: '100%',
@@ -171,7 +170,9 @@ export function Slider(props: SliderProps) {
return ( return (
<div style={divStyle}> <div style={divStyle}>
<div style={trackStyle} /> <div style={trackStyle} />
<div style={thumbStyle} /> <div style={thumbStyle}>
{props.children}
</div>
<input <input
className={className} className={className}
{...Utils.controlEvents(props)} {...Utils.controlEvents(props)}

View File

@@ -17,8 +17,6 @@ export interface TextInputProps extends Noodl.ReactProps {
type: 'text' | 'textArea' | 'email' | 'number' | 'password' | 'url'; type: 'text' | 'textArea' | 'email' | 'number' | 'password' | 'url';
textStyle: Noodl.TextStyle; textStyle: Noodl.TextStyle;
attrs: React.Attributes;
enabled: boolean; enabled: boolean;
placeholder: string; placeholder: string;
@@ -151,7 +149,6 @@ export class TextInput extends React.Component<TextInputProps, State> {
inputStyles.color = props.noodlNode.context.styles.resolveColor(inputStyles.color); inputStyles.color = props.noodlNode.context.styles.resolveColor(inputStyles.color);
const inputProps = { const inputProps = {
...props.attrs,
id: props.id, id: props.id,
value: this.state.value, value: this.state.value,
...Utils.controlEvents(props), ...Utils.controlEvents(props),

View File

@@ -7,8 +7,6 @@ export interface ColumnsProps extends Noodl.ReactProps {
marginX: string; marginX: string;
marginY: string; marginY: string;
attrs: React.Attributes;
justifyContent: 'flex-start' | 'flex-end' | 'center'; justifyContent: 'flex-start' | 'flex-end' | 'center';
direction: 'row' | 'column'; direction: 'row' | 'column';
minWidth: string; minWidth: string;
@@ -117,10 +115,7 @@ export function Columns(props: ColumnsProps) {
// ForEachCompoent breaks the layout but is needed to send onMount/onUnmount // ForEachCompoent breaks the layout but is needed to send onMount/onUnmount
if (!Array.isArray(props.children)) { if (!Array.isArray(props.children)) {
// @ts-expect-error props.children.type is any children = [props.children];
if (props.children.type !== ForEachComponent) {
children = [props.children]
}
} else { } else {
children = props.children.filter((child) => child.type !== ForEachComponent); children = props.children.filter((child) => child.type !== ForEachComponent);
forEachComponent = props.children.find((child) => child.type === ForEachComponent); forEachComponent = props.children.find((child) => child.type === ForEachComponent);
@@ -128,11 +123,9 @@ export function Columns(props: ColumnsProps) {
return ( return (
<div <div
{...props.attrs}
className={['columns-container', props.className].join(' ')} className={['columns-container', props.className].join(' ')}
ref={containerRef} ref={containerRef}
style={{ style={{
visibility: containerWidth === null ? "hidden" : "visible",
marginTop: parseFloat(props.marginY) * -1, marginTop: parseFloat(props.marginY) * -1,
marginLeft: parseFloat(props.marginX) * -1, marginLeft: parseFloat(props.marginX) * -1,
display: 'flex', display: 'flex',

View File

@@ -19,8 +19,6 @@ BScroll.use(Slide);
export interface GroupProps extends Noodl.ReactProps { export interface GroupProps extends Noodl.ReactProps {
as?: keyof JSX.IntrinsicElements | React.ComponentType<unknown>; as?: keyof JSX.IntrinsicElements | React.ComponentType<unknown>;
attrs: React.Attributes;
scrollSnapEnabled: boolean; scrollSnapEnabled: boolean;
showScrollbar: boolean; showScrollbar: boolean;
scrollEnabled: boolean; scrollEnabled: boolean;
@@ -273,7 +271,6 @@ export class Group extends React.Component<GroupProps> {
<Component <Component
// @ts-expect-error Lets hope that the type passed here is always static! // @ts-expect-error Lets hope that the type passed here is always static!
className={props.className} className={props.className}
{...props.attrs}
{...props.dom} {...props.dom}
{...PointerListeners(props)} {...PointerListeners(props)}
style={style} style={style}

View File

@@ -10,7 +10,6 @@ export interface ImageProps extends Noodl.ReactProps {
src: string; src: string;
onLoad?: () => void; onLoad?: () => void;
}; };
attrs: React.Attributes;
} }
export function Image(props: ImageProps) { export function Image(props: ImageProps) {
@@ -31,5 +30,5 @@ export function Image(props: ImageProps) {
} }
} }
return <img {...props.attrs} className={props.className} {...props.dom} {...PointerListeners(props)} style={style} />; return <img className={props.className} {...props.dom} {...PointerListeners(props)} style={style} />;
} }

View File

@@ -7,8 +7,6 @@ import { Noodl } from '../../../types';
export interface TextProps extends Noodl.ReactProps { export interface TextProps extends Noodl.ReactProps {
as?: keyof JSX.IntrinsicElements | React.ComponentType<unknown>; as?: keyof JSX.IntrinsicElements | React.ComponentType<unknown>;
attrs: React.Attributes;
textStyle: Noodl.TextStyle; textStyle: Noodl.TextStyle;
text: string; text: string;
@@ -50,7 +48,6 @@ export function Text(props: TextProps) {
return ( return (
<Component <Component
className={['ndl-visual-text', props.className].join(' ')} className={['ndl-visual-text', props.className].join(' ')}
{...props.attrs}
{...props.dom} {...props.dom}
{...PointerListeners(props)} {...PointerListeners(props)}
style={style} style={style}

View File

@@ -30,24 +30,11 @@ const ButtonNode = {
] ]
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.layout = 'row'; //Used to tell child nodes what layout to expect this.props.layout = 'row'; //Used to tell child nodes what layout to expect
}, },
getReactComponent() { getReactComponent() {
return Button; return Button;
}, },
inputs: {
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
}
},
inputCss: { inputCss: {
backgroundColor: { backgroundColor: {
index: 100, index: 100,

View File

@@ -31,7 +31,6 @@ const CheckBoxNode = {
] ]
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.sizeMode = 'explicit'; this.props.sizeMode = 'explicit';
this.props.id = 'input-' + guid(); this.props.id = 'input-' + guid();
this.props.checked = this._internal.checked = false; this.props.checked = this._internal.checked = false;
@@ -95,16 +94,6 @@ const CheckBoxNode = {
this.flagOutputDirty('checked'); this.flagOutputDirty('checked');
this._updateVisualState(); this._updateVisualState();
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputCss: { inputCss: {

View File

@@ -31,7 +31,6 @@ const OptionsNode = {
] ]
}, },
initialize: function () { initialize: function () {
this.props.attrs = {};
this._itemsChanged = () => { this._itemsChanged = () => {
this.forceUpdate(); this.forceUpdate();
}; };
@@ -91,16 +90,6 @@ const OptionsNode = {
this.flagOutputDirty('value'); this.flagOutputDirty('value');
} }
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputProps: { inputProps: {

View File

@@ -31,7 +31,6 @@ const RadioButtonNode = {
] ]
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.sizeMode = 'explicit'; this.props.sizeMode = 'explicit';
this.props.id = 'input-' + guid(); this.props.id = 'input-' + guid();
@@ -62,16 +61,6 @@ const RadioButtonNode = {
set(value) { set(value) {
this.setStyle({ backgroundColor: value }, 'fill'); this.setStyle({ backgroundColor: value }, 'fill');
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputProps: { inputProps: {

View File

@@ -11,7 +11,6 @@ const RangeNode = {
name: 'net.noodl.controls.range', name: 'net.noodl.controls.range',
displayNodeName: 'Slider', displayNodeName: 'Slider',
docs: 'https://docs.noodl.net/nodes/ui-controls/slider', docs: 'https://docs.noodl.net/nodes/ui-controls/slider',
allowChildren: false,
noodlNodeAsProp: true, noodlNodeAsProp: true,
connectionPanel: { connectionPanel: {
groupPriority: [ groupPriority: [
@@ -27,7 +26,6 @@ const RangeNode = {
] ]
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.sizeMode = 'contentHeight'; this.props.sizeMode = 'contentHeight';
this.props.id = 'input-' + guid(); this.props.id = 'input-' + guid();
@@ -68,16 +66,6 @@ const RangeNode = {
set(value) { set(value) {
this._setInputValue(value); this._setInputValue(value);
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
outputs: { outputs: {

View File

@@ -43,7 +43,6 @@ const TextInputNode = {
return TextInput; return TextInput;
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.startValue = ''; this.props.startValue = '';
this.props.id = this._internal.controlId = 'input-' + guid(); this.props.id = this._internal.controlId = 'input-' + guid();
}, },
@@ -168,16 +167,6 @@ const TextInputNode = {
break; break;
} }
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputCss: { inputCss: {

View File

@@ -72,10 +72,8 @@ const Navigate = {
backCallback: (action, results) => { backCallback: (action, results) => {
this._internal.backResults = results; this._internal.backResults = results;
for (const key in results) { for (var key in results) {
if (this.hasOutput('backResult-' + key)) { if (this.hasOutput('backResult-' + key)) this.flagOutputDirty('backResult-' + key);
this.flagOutputDirty('backResult-' + key);
}
} }
if (action !== undefined) this.sendSignalOnOutput(action); if (action !== undefined) this.sendSignalOnOutput(action);
@@ -116,23 +114,22 @@ const Navigate = {
return; return;
} }
if (name === 'target') { if (name === 'target')
return this.registerInput(name, { return this.registerInput(name, {
set: this.setTargetPageId.bind(this) set: this.setTargetPageId.bind(this)
}); });
} else if (name === 'transition') { else if (name === 'transition')
return this.registerInput(name, { return this.registerInput(name, {
set: this.setTransition.bind(this) set: this.setTransition.bind(this)
}); });
} else if (name.startsWith('tr-')) { else if (name.startsWith('tr-'))
return this.registerInput(name, { return this.registerInput(name, {
set: this.setTransitionParam.bind(this, name.substring('tr-'.length)) set: this.setTransitionParam.bind(this, name.substring('tr-'.length))
}); });
} else if (name.startsWith('pm-')) { else if (name.startsWith('pm-'))
return this.registerInput(name, { return this.registerInput(name, {
set: this.setPageParam.bind(this, name.substring('pm-'.length)) set: this.setPageParam.bind(this, name.substring('pm-'.length))
}); });
}
}, },
registerOutputIfNeeded: function (name) { registerOutputIfNeeded: function (name) {
if (this.hasOutput(name)) { if (this.hasOutput(name)) {
@@ -177,24 +174,18 @@ function setup(context, graphModel) {
if (Transitions[transition]) ports = ports.concat(Transitions[transition].ports(node.parameters)); if (Transitions[transition]) ports = ports.concat(Transitions[transition].ports(node.parameters));
} }
const pageStacks = graphModel.getNodesWithType('Page Stack'); // if(node.parameters['stack'] !== undefined) {
const pageStack = pageStacks.find( var pageStacks = graphModel.getNodesWithType('Page Stack');
var pageStack = pageStacks.find(
(ps) => (ps.parameters['name'] || 'Main') === (node.parameters['stack'] || 'Main') (ps) => (ps.parameters['name'] || 'Main') === (node.parameters['stack'] || 'Main')
); );
if (pageStack !== undefined) { if (pageStack !== undefined) {
const pages = pageStack.parameters['pages']; var pages = pageStack.parameters['pages'];
if (pages !== undefined && pages.length > 0) { if (pages !== undefined && pages.length > 0) {
ports.push({ ports.push({
plug: 'input', plug: 'input',
type: { type: { name: 'enum', enums: pages.map((p) => ({ label: p.label, value: p.id })), allowEditOnly: true },
name: 'enum',
enums: pages.map((p) => ({
label: p.label,
value: p.id
})),
allowEditOnly: true
},
group: 'General', group: 'General',
displayName: 'Target Page', displayName: 'Target Page',
name: 'target', name: 'target',
@@ -202,14 +193,14 @@ function setup(context, graphModel) {
}); });
// See if there is a target page with component // See if there is a target page with component
const targetPageId = node.parameters['target'] || pages[0].id; var targetPageId = node.parameters['target'] || pages[0].id;
const targetComponentName = pageStack.parameters['pageComp-' + targetPageId]; var targetComponentName = pageStack.parameters['pageComp-' + targetPageId];
if (targetComponentName !== undefined) { if (targetComponentName !== undefined) {
const component = graphModel.components[targetComponentName]; const component = graphModel.components[targetComponentName];
if (component !== undefined) { if (component !== undefined) {
// Make all inputs of the component to inputs of this navigation node // Make all inputs of the component to inputs of this navigation node
for (const inputName in component.inputPorts) { for (var inputName in component.inputPorts) {
ports.push({ ports.push({
name: 'pm-' + inputName, name: 'pm-' + inputName,
displayName: inputName, displayName: inputName,
@@ -254,6 +245,7 @@ function setup(context, graphModel) {
} }
} }
} }
// }
context.editorConnection.sendDynamicPorts(node.id, ports); context.editorConnection.sendDynamicPorts(node.id, ports);
} }

View File

@@ -43,10 +43,6 @@ const OpenFilePicker = {
input.accept = this._internal.acceptedFileTypes; input.accept = this._internal.acceptedFileTypes;
if (this._internal.capture) {
input.capture = this._internal.capture;
}
input.onchange = onChange; input.onchange = onChange;
input.click(); input.click();
} }
@@ -58,14 +54,6 @@ const OpenFilePicker = {
set(value) { set(value) {
this._internal.acceptedFileTypes = value; this._internal.acceptedFileTypes = value;
} }
},
capture: {
group: 'General',
type: 'string',
displayName: 'Capture',
set(value) {
this._internal.capture = value;
}
} }
}, },
outputs: { outputs: {

View File

@@ -4,7 +4,7 @@ const Switch = {
name: 'Switch', name: 'Switch',
docs: 'https://docs.noodl.net/nodes/logic/switch', docs: 'https://docs.noodl.net/nodes/logic/switch',
category: 'Logic', category: 'Logic',
initialize() { initialize: function () {
this._internal.state = false; this._internal.state = false;
this._internal.initialized = false; this._internal.initialized = false;
}, },
@@ -15,7 +15,7 @@ const Switch = {
on: { on: {
displayName: 'On', displayName: 'On',
group: 'Change State', group: 'Change State',
valueChangedToTrue() { valueChangedToTrue: function () {
if (this._internal.state === true) { if (this._internal.state === true) {
return; return;
} }
@@ -27,7 +27,7 @@ const Switch = {
off: { off: {
displayName: 'Off', displayName: 'Off',
group: 'Change State', group: 'Change State',
valueChangedToTrue() { valueChangedToTrue: function () {
if (this._internal.state === false) { if (this._internal.state === false) {
return; return;
} }
@@ -39,7 +39,7 @@ const Switch = {
flip: { flip: {
displayName: 'Flip', displayName: 'Flip',
group: 'Change State', group: 'Change State',
valueChangedToTrue() { valueChangedToTrue: function () {
this._internal.state = !this._internal.state; this._internal.state = !this._internal.state;
this.flagOutputDirty('state'); this.flagOutputDirty('state');
this.emitSignals(); this.emitSignals();
@@ -50,7 +50,7 @@ const Switch = {
displayName: 'State', displayName: 'State',
group: 'General', group: 'General',
default: false, default: false,
set(value) { set: function (value) {
this._internal.state = !!value; this._internal.state = !!value;
this.flagOutputDirty('state'); this.flagOutputDirty('state');
this.emitSignals(); this.emitSignals();
@@ -61,15 +61,10 @@ const Switch = {
state: { state: {
type: 'boolean', type: 'boolean',
displayName: 'Current State', displayName: 'Current State',
getter() { getter: function () {
return this._internal.state; return this._internal.state;
} }
}, },
switched: {
displayName: 'Switched',
type: 'signal',
group: 'Signals'
},
switchedToOn: { switchedToOn: {
displayName: 'Switched To On', displayName: 'Switched To On',
type: 'signal', type: 'signal',
@@ -82,13 +77,12 @@ const Switch = {
} }
}, },
prototypeExtensions: { prototypeExtensions: {
emitSignals() { emitSignals: function () {
if (this._internal.state === true) { if (this._internal.state === true) {
this.sendSignalOnOutput('switchedToOn'); this.sendSignalOnOutput('switchedToOn');
} else { } else {
this.sendSignalOnOutput('switchedToOff'); this.sendSignalOnOutput('switchedToOff');
} }
this.sendSignalOnOutput('switched');
} }
} }
}; };

View File

@@ -1,13 +1,18 @@
'use strict'; 'use strict';
const { Node, EdgeTriggeredInput } = require('@noodl/runtime');
const UserService = require('./userservice'); const UserService = require('./userservice');
const LoginNodeDefinition = { var LoginNodeDefinition = {
name: 'net.noodl.user.LogIn', name: 'net.noodl.user.LogIn',
docs: 'https://docs.noodl.net/nodes/data/user/log-in', docs: 'https://docs.noodl.net/nodes/data/user/log-in',
displayNodeName: 'Log In', displayNodeName: 'Log In',
category: 'Cloud Services', category: 'Cloud Services',
color: 'data', color: 'data',
initialize: function () {
var internal = this._internal;
},
getInspectInfo() {},
outputs: { outputs: {
success: { success: {
type: 'signal', type: 'signal',
@@ -23,7 +28,7 @@ const LoginNodeDefinition = {
type: 'string', type: 'string',
displayName: 'Error', displayName: 'Error',
group: 'Error', group: 'Error',
getter() { getter: function () {
return this._internal.error; return this._internal.error;
} }
} }
@@ -32,7 +37,7 @@ const LoginNodeDefinition = {
login: { login: {
displayName: 'Do', displayName: 'Do',
group: 'Actions', group: 'Actions',
valueChangedToTrue() { valueChangedToTrue: function () {
this.scheduleLogIn(); this.scheduleLogIn();
} }
}, },
@@ -40,7 +45,7 @@ const LoginNodeDefinition = {
displayName: 'Username', displayName: 'Username',
type: 'string', type: 'string',
group: 'General', group: 'General',
set(value) { set: function (value) {
this._internal.username = value; this._internal.username = value;
} }
}, },
@@ -48,13 +53,13 @@ const LoginNodeDefinition = {
displayName: 'Password', displayName: 'Password',
type: 'string', type: 'string',
group: 'General', group: 'General',
set(value) { set: function (value) {
this._internal.password = value; this._internal.password = value;
} }
} }
}, },
methods: { methods: {
setError(err) { setError: function (err) {
this._internal.error = err; this._internal.error = err;
this.flagOutputDirty('error'); this.flagOutputDirty('error');
this.sendSignalOnOutput('failure'); this.sendSignalOnOutput('failure');
@@ -71,7 +76,9 @@ const LoginNodeDefinition = {
this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning'); this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning');
} }
}, },
scheduleLogIn() { scheduleLogIn: function () {
const internal = this._internal;
if (this.logInScheduled === true) return; if (this.logInScheduled === true) return;
this.logInScheduled = true; this.logInScheduled = true;
@@ -93,7 +100,89 @@ const LoginNodeDefinition = {
} }
}; };
/*function updatePorts(nodeId, parameters, editorConnection, dbCollections) {
var ports = [];
ports.push({
name: 'collectionName',
displayName: "Class",
group: "General",
type: { name: 'enum', enums: (dbCollections !== undefined) ? dbCollections.map((c) => { return { value: c.name, label: c.name } }) : [], allowEditOnly: true },
plug: 'input'
})
if (parameters.collectionName && dbCollections) {
// Fetch ports from collection keys
var c = dbCollections.find((c) => c.name === parameters.collectionName);
if (c && c.schema && c.schema.properties) {
var props = c.schema.properties;
for (var key in props) {
var p = props[key];
if (ports.find((_p) => _p.name === key)) continue;
if(p.type === 'Relation') {
}
else { // Other schema type ports
const _typeMap = {
"String":"string",
"Boolean":"boolean",
"Number":"number",
"Date":"date"
}
ports.push({
type: {
name: _typeMap[p.type]?_typeMap[p.type]:'*',
},
plug: 'output',
group: 'Properties',
name: 'prop-' + key,
displayName: key,
})
ports.push({
type: 'signal',
plug: 'output',
group: 'Changed Events',
displayName: key+ ' Changed',
name: 'changed-' + key,
})
}
}
}
}
editorConnection.sendDynamicPorts(nodeId, ports);
}*/
module.exports = { module.exports = {
node: LoginNodeDefinition, node: LoginNodeDefinition,
setup(_context, _graphModel) {} setup: function (context, graphModel) {
/* if (!context.editorConnection || !context.editorConnection.isRunningLocally()) {
return;
}
function _managePortsForNode(node) {
updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('dbCollections'));
node.on("parameterUpdated", function (event) {
updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('dbCollections'));
});
graphModel.on('metadataChanged.dbCollections', function (data) {
updatePorts(node.id, node.parameters, context.editorConnection, data);
})
}
graphModel.on("editorImportComplete", ()=> {
graphModel.on("nodeAdded.DbModel2", function (node) {
_managePortsForNode(node)
})
for(const node of graphModel.getNodesWithType('DbModel2')) {
_managePortsForNode(node)
}
})*/
}
}; };

View File

@@ -1,13 +1,18 @@
'use strict'; 'use strict';
const { Node, EdgeTriggeredInput } = require('@noodl/runtime');
const UserService = require('./userservice'); const UserService = require('./userservice');
const LogOutNodeDefinition = { var LogOutNodeDefinition = {
name: 'net.noodl.user.LogOut', name: 'net.noodl.user.LogOut',
docs: 'https://docs.noodl.net/nodes/data/user/log-out', docs: 'https://docs.noodl.net/nodes/data/user/log-out',
displayNodeName: 'Log Out', displayNodeName: 'Log Out',
category: 'Cloud Services', category: 'Cloud Services',
color: 'data', color: 'data',
initialize: function () {
var internal = this._internal;
},
getInspectInfo() {},
outputs: { outputs: {
success: { success: {
type: 'signal', type: 'signal',
@@ -23,7 +28,7 @@ const LogOutNodeDefinition = {
type: 'string', type: 'string',
displayName: 'Error', displayName: 'Error',
group: 'Error', group: 'Error',
getter() { getter: function () {
return this._internal.error; return this._internal.error;
} }
} }
@@ -32,13 +37,13 @@ const LogOutNodeDefinition = {
login: { login: {
displayName: 'Do', displayName: 'Do',
group: 'Actions', group: 'Actions',
valueChangedToTrue() { valueChangedToTrue: function () {
this.scheduleLogOut(); this.scheduleLogOut();
} }
} }
}, },
methods: { methods: {
setError(err) { setError: function (err) {
this._internal.error = err; this._internal.error = err;
this.flagOutputDirty('error'); this.flagOutputDirty('error');
this.sendSignalOnOutput('failure'); this.sendSignalOnOutput('failure');
@@ -55,7 +60,9 @@ const LogOutNodeDefinition = {
this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning'); this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning');
} }
}, },
scheduleLogOut() { scheduleLogOut: function () {
const internal = this._internal;
if (this.logOutScheduled === true) return; if (this.logOutScheduled === true) return;
this.logOutScheduled = true; this.logOutScheduled = true;
@@ -77,5 +84,5 @@ const LogOutNodeDefinition = {
module.exports = { module.exports = {
node: LogOutNodeDefinition, node: LogOutNodeDefinition,
setup(_context, _graphModel) {} setup: function (context, graphModel) {}
}; };

View File

@@ -1,17 +1,20 @@
'use strict'; 'use strict';
const { Node, EdgeTriggeredInput } = require('@noodl/runtime');
const UserService = require('./userservice'); const UserService = require('./userservice');
const SignUpNodeDefinition = { var SignUpNodeDefinition = {
name: 'net.noodl.user.SignUp', name: 'net.noodl.user.SignUp',
docs: 'https://docs.noodl.net/nodes/data/user/sign-up', docs: 'https://docs.noodl.net/nodes/data/user/sign-up',
displayNodeName: 'Sign Up', displayNodeName: 'Sign Up',
category: 'Cloud Services', category: 'Cloud Services',
color: 'data', color: 'data',
initialize() { initialize: function () {
const internal = this._internal; var internal = this._internal;
internal.userProperties = {}; internal.userProperties = {};
}, },
getInspectInfo() {},
outputs: { outputs: {
success: { success: {
type: 'signal', type: 'signal',
@@ -27,7 +30,7 @@ const SignUpNodeDefinition = {
type: 'string', type: 'string',
displayName: 'Error', displayName: 'Error',
group: 'Error', group: 'Error',
getter() { getter: function () {
return this._internal.error; return this._internal.error;
} }
} }
@@ -36,7 +39,7 @@ const SignUpNodeDefinition = {
signup: { signup: {
displayName: 'Do', displayName: 'Do',
group: 'Actions', group: 'Actions',
valueChangedToTrue() { valueChangedToTrue: function () {
this.scheduleSignUp(); this.scheduleSignUp();
} }
}, },
@@ -44,7 +47,7 @@ const SignUpNodeDefinition = {
displayName: 'Username', displayName: 'Username',
type: 'string', type: 'string',
group: 'General', group: 'General',
set(value) { set: function (value) {
this._internal.username = value; this._internal.username = value;
} }
}, },
@@ -52,7 +55,7 @@ const SignUpNodeDefinition = {
displayName: 'Password', displayName: 'Password',
type: 'string', type: 'string',
group: 'General', group: 'General',
set(value) { set: function (value) {
this._internal.password = value; this._internal.password = value;
} }
}, },
@@ -60,13 +63,13 @@ const SignUpNodeDefinition = {
displayName: 'Email', displayName: 'Email',
type: 'string', type: 'string',
group: 'General', group: 'General',
set(value) { set: function (value) {
this._internal.email = value; this._internal.email = value;
} }
} }
}, },
methods: { methods: {
setError(err) { setError: function (err) {
this._internal.error = err; this._internal.error = err;
this.flagOutputDirty('error'); this.flagOutputDirty('error');
this.sendSignalOnOutput('failure'); this.sendSignalOnOutput('failure');
@@ -83,7 +86,7 @@ const SignUpNodeDefinition = {
this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning'); this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning');
} }
}, },
scheduleSignUp() { scheduleSignUp: function () {
const internal = this._internal; const internal = this._internal;
if (this.signUpScheduled === true) return; if (this.signUpScheduled === true) return;
@@ -106,24 +109,23 @@ const SignUpNodeDefinition = {
}); });
}); });
}, },
setUserProperty(name, value) { setUserProperty: function (name, value) {
this._internal.userProperties[name] = value; this._internal.userProperties[name] = value;
}, },
registerInputIfNeeded(name) { registerInputIfNeeded: function (name) {
if (this.hasInput(name)) { if (this.hasInput(name)) {
return; return;
} }
if (name.startsWith('prop-')) { if (name.startsWith('prop-'))
return this.registerInput(name, { return this.registerInput(name, {
set: this.setUserProperty.bind(this, name.substring('prop-'.length)) set: this.setUserProperty.bind(this, name.substring('prop-'.length))
}); });
}
} }
} }
}; };
function updatePorts(nodeId, _parameters, editorConnection, systemCollections) { function updatePorts(nodeId, parameters, editorConnection, systemCollections) {
var ports = []; var ports = [];
if (systemCollections) { if (systemCollections) {
@@ -167,7 +169,7 @@ function updatePorts(nodeId, _parameters, editorConnection, systemCollections) {
module.exports = { module.exports = {
node: SignUpNodeDefinition, node: SignUpNodeDefinition,
setup(context, graphModel) { setup: function (context, graphModel) {
if (!context.editorConnection || !context.editorConnection.isRunningLocally()) { if (!context.editorConnection || !context.editorConnection.isRunningLocally()) {
return; return;
} }
@@ -175,7 +177,7 @@ module.exports = {
function _managePortsForNode(node) { function _managePortsForNode(node) {
updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('systemCollections')); updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('systemCollections'));
node.on('parameterUpdated', function (_event) { node.on('parameterUpdated', function (event) {
updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('systemCollections')); updatePorts(node.id, node.parameters, context.editorConnection, graphModel.getMetaData('systemCollections'));
}); });

View File

@@ -23,7 +23,7 @@ const ColumnsNode = {
] ]
}, },
initialize() { this.props.attrs = {}; initialize() {
this.props.layoutString = '1 2 1'; this.props.layoutString = '1 2 1';
this.props.minWidth = 0; this.props.minWidth = 0;
this.props.marginX = 16; this.props.marginX = 16;
@@ -62,16 +62,6 @@ const ColumnsNode = {
); );
} }
this.forceUpdate();
}
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate(); this.forceUpdate();
} }
} }

View File

@@ -11,7 +11,6 @@ const GroupNode = {
groupPriority: ['General', 'Style', 'Events', 'Mounted', 'Hover Events', 'Pointer Events', 'Focus', 'Scroll'] groupPriority: ['General', 'Style', 'Events', 'Mounted', 'Hover Events', 'Pointer Events', 'Focus', 'Scroll']
}, },
initialize() { initialize() {
this.props.attrs = {};
this._internal = { this._internal = {
scrollElementDuration: 500, scrollElementDuration: 500,
scrollIndexDuration: 500, scrollIndexDuration: 500,
@@ -144,16 +143,6 @@ const GroupNode = {
valueChangedToTrue() { valueChangedToTrue() {
this.context.setNodeFocused(this, true); this.context.setNodeFocused(this, true);
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputProps: { inputProps: {

View File

@@ -27,7 +27,6 @@ const ImageNode = {
] ]
}, },
initialize() { initialize() {
this.props.attrs = {};
this.props.default = ''; this.props.default = '';
}, },
getReactComponent() { getReactComponent() {
@@ -87,16 +86,6 @@ const ImageNode = {
this.props.dom.src = getAbsoluteUrl(url); this.props.dom.src = getAbsoluteUrl(url);
this.forceUpdate(); this.forceUpdate();
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
}, },
inputProps: { inputProps: {
@@ -125,12 +114,6 @@ const ImageNode = {
propPath: 'dom', propPath: 'dom',
type: 'signal', type: 'signal',
group: 'Events' group: 'Events'
},
onError: {
displayName: 'On Error',
propPath: 'dom',
type: 'signal',
group: 'Events'
} }
} }
}; };

View File

@@ -20,9 +20,6 @@ const TextNode = {
nodeDoubleClickAction: { nodeDoubleClickAction: {
focusPort: 'text' focusPort: 'text'
}, },
initialize() {
this.props.attrs = {};
},
getReactComponent() { getReactComponent() {
return Text; return Text;
}, },
@@ -138,16 +135,6 @@ const TextNode = {
break; break;
} }
} }
},
testId: {
index: 100009,
displayName: 'Test ID Attribute',
group: 'Advanced HTML',
type: 'string',
set(value) {
this.props.attrs["data-testid"] = value;
this.forceUpdate();
}
} }
} }
}; };

View File

@@ -6,7 +6,7 @@ export default {
group: 'General', group: 'General',
plug: 'input', plug: 'input',
type: 'string', type: 'string',
default: 'Fluxscape Viewer', default: 'Noodl Viewer',
tooltip: 'The title that web browsers show', tooltip: 'The title that web browsers show',
ignoreInExport: true ignoreInExport: true
}, },

View File

@@ -131,59 +131,6 @@ declare namespace Noodl {
*/ */
const Events: EventsApi; const Events: EventsApi;
type RecordQuery<T> =
{
lessThan: T
} |
{
lessThanOrEqualTo: T
} |
{
greaterThan: T
} |
{
greaterThanOrEqualTo: T
} |
{
equalTo: T
} |
{
notEqualTo: T
} |
{
containedIn: T
} |
{
notContainedIn : T
} |
{
exists: T
} |
{
matchesRegex: T
} |
{
text: T
} |
{
idEqualTo: T
} |
{
idContainedIn: T
} |
{
pointsTo: T
} |
{
relatedTo: T
};
type RecordQueryField<T> = T extends RecordQuery<any> ?
{ [K in keyof T]: { [P in K]: T[P] } & Partial<Record<Exclude<keyof T, K>, never>> }[keyof T]
: never;
type RecordSortKey<T extends string> = (`${T}` | `-${T}`)[];
interface RecordsApi { interface RecordsApi {
/** /**
* This is an async function that will query the database using the query * This is an async function that will query the database using the query
@@ -225,17 +172,15 @@ declare namespace Noodl {
* }) * })
* ``` * ```
*/ */
query<TClassName extends RecordClassName>( query(
className: TClassName, className: RecordClassName,
query?: query?: any,
RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }> |
{ and: RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }>[] },
options?: { options?: {
limit?: number; limit?: number;
skip?: number; skip?: number;
sort?: string | RecordSortKey<keyof DatabaseSchema[TClassName]>; sort?: string[];
include?: string | (keyof DatabaseSchema[TClassName])[]; include?: any;
select?: string | (keyof DatabaseSchema[TClassName])[]; select?: any;
} }
): Promise<any>; ): Promise<any>;

View File

@@ -73,17 +73,17 @@ import { getCurrentPlatform } from '../helper';
// It basically means that some package is not relative to this path. // It basically means that some package is not relative to this path.
console.log("--- Run 'npm install' ..."); console.log("--- Run 'npm install' ...");
if (platform === 'darwin') { if (platform === "darwin") {
execSync(`npm install electron-notarize`, { execSync(`npm install electron-notarize`, {
stdio: 'inherit', stdio: 'inherit',
env: process.env env: process.env
}); })
} }
execSync(`npm install --arch=${arch} --scope fluxscape-editor`, { execSync(`npm install --arch=${arch} --scope noodl-editor`, {
stdio: 'inherit', stdio: 'inherit',
env: process.env env: process.env
}); })
console.log("--- 'npm install' done!"); console.log("--- 'npm install' done!");
// NOTE: npm install --arch= does this too // NOTE: npm install --arch= does this too
@@ -99,13 +99,13 @@ import { getCurrentPlatform } from '../helper';
// Build: Replace "dugite" // Build: Replace "dugite"
// Build: Replace "desktop-trampoline" // Build: Replace "desktop-trampoline"
console.log("--- Run 'npm run build' ..."); console.log("--- Run 'npm run build' ...");
execSync('npx lerna exec --scope fluxscape-editor -- npm run build', { execSync('npx lerna exec --scope noodl-editor -- npm run build', {
stdio: 'inherit', stdio: 'inherit',
env: { env: {
...process.env, ...process.env,
TARGET_PLATFORM, TARGET_PLATFORM,
DISABLE_SIGNING, DISABLE_SIGNING,
CSC_NAME CSC_NAME,
} }
}); });
console.log("--- 'npm run build' done!"); console.log("--- 'npm run build' done!");

View File

@@ -74,7 +74,7 @@ const cloudRuntimeProcess = attachStdio(
} }
); );
const editorProcess = attachStdio(exec('npx lerna exec --scope fluxscape-editor -- npm run start', processOptions), { const editorProcess = attachStdio(exec('npx lerna exec --scope noodl-editor -- npm run start', processOptions), {
prefix: 'Editor', prefix: 'Editor',
color: ConsoleColor.FgCyan color: ConsoleColor.FgCyan
}); });

View File

@@ -1,27 +1,36 @@
import { execSync } from 'child_process'; import path from "path";
import path from 'path'; import { execSync } from "child_process";
const CWD = path.join(__dirname, '..'); const CWD = path.join(__dirname, "..");
const LOCAL_GIT_DIRECTORY = path.join(__dirname, '..', 'node_modules', 'dugite', 'git'); const LOCAL_GIT_DIRECTORY = path.join(
__dirname,
"..",
"node_modules",
"dugite",
"git"
);
const LOCAL_GIT_TRAMPOLINE_DIRECTORY = path.join( const LOCAL_GIT_TRAMPOLINE_DIRECTORY = path.join(
__dirname, __dirname,
'..', "..",
'node_modules', "node_modules",
'desktop-trampoline/build/Release/desktop-trampoline' "desktop-trampoline/build/Release/desktop-trampoline"
); );
console.log('---'); console.log("---");
console.log(`> CWD: `, CWD); console.log(`> CWD: `, CWD);
console.log(`> LOCAL_GIT_DIRECTORY: `, LOCAL_GIT_DIRECTORY); console.log(`> LOCAL_GIT_DIRECTORY: `, LOCAL_GIT_DIRECTORY);
console.log(`> LOCAL_GIT_TRAMPOLINE_DIRECTORY: `, LOCAL_GIT_TRAMPOLINE_DIRECTORY); console.log(
console.log('---'); `> LOCAL_GIT_TRAMPOLINE_DIRECTORY: `,
LOCAL_GIT_TRAMPOLINE_DIRECTORY
);
console.log("---");
execSync('npx lerna exec --scope fluxscape-editor -- npm run test', { execSync("npx lerna exec --scope noodl-editor -- npm run test", {
cwd: CWD, cwd: CWD,
stdio: 'inherit', stdio: "inherit",
env: { env: {
...process.env, ...process.env,
LOCAL_GIT_DIRECTORY, LOCAL_GIT_DIRECTORY,
LOCAL_GIT_TRAMPOLINE_DIRECTORY LOCAL_GIT_TRAMPOLINE_DIRECTORY,
} },
}); });