18 Commits

Author SHA1 Message Date
Eric Tuvesson
94dd3dbf0e chore: bump version (#62) 2024-08-08 21:27:12 +02:00
Eric Tuvesson
c593a134b3 chore: rename project name (#60) 2024-08-08 21:23:23 +02:00
Eric Tuvesson
dc638ea8fc feat: Upgrade Electron (#61) 2024-08-08 21:12:39 +02:00
Eric Tuvesson
759c8a0030 fix(runtime): Column node, hide children on calculation (#59)
This removes the initial visible layout shift
2024-07-24 15:59:10 +02:00
Eric Tuvesson
aea80c6586 feat(runtime): Add capture attribute on Open File Picker node (#57)
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#capture
- https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/capture
2024-07-19 15:03:03 +02:00
Eric Tuvesson
46e2efa576 feat(runtime): Add "Switched" signal output on the Switch node (#58) 2024-07-19 15:02:49 +02:00
Eric Tuvesson
c508e15546 chore: clean up user nodes (#53) 2024-07-15 15:21:01 +02:00
Eric Tuvesson
d61effc615 feat(editor): Deploy popup always mounted (#51)
This removes the delayed loading when opening the deploy popup
2024-07-08 12:47:28 +02:00
Eric Tuvesson
12be6dc69f feat(editor): Upgrade electron (#50) 2024-07-08 09:35:18 +02:00
Eric Tuvesson
17e3d16436 chore: clean up editor assets (#12) 2024-07-08 08:09:39 +02:00
Eric Tuvesson
233479a1bc feat: Add Support for Parse Server v7 (#20)
* feat: Upgrade Aggregate queries to latest Parse API

* feat: Save parse server major version in metadata

This can be used to determine which version of the Parse API that will be used.

* fix: Add support for both versions of aggregate queries
2024-07-08 08:06:47 +02:00
Eric Tuvesson
57e5246022 feat(runtime): Add default label to String Format node (#49)
Update the String Format node default label to show the format, like how the other nodes work.
2024-07-04 15:54:20 +02:00
Eric Tuvesson
dda22e0de6 feat(runtime): Add Image node output "On Error" signal (#48)
"On Error" is triggered when the image is not loading correctly, making it possible to hide the Image node or show a placeholder instead.
2024-07-04 14:02:34 +02:00
Eric Tuvesson
618955e1ee feat: Portal include Project ID (#47) 2024-06-28 00:43:34 +02:00
Eric Tuvesson
8c7d4faeca fix(runtime): Column node added a div with empty Repeater (#45)
When the Column node only had an empty Repeater child, there was an empty HTML element.
2024-06-27 21:16:50 +02:00
Eric Tuvesson
c5754c9160 feat(runtime): Add "data-testId" attribute to Columns node (#44) 2024-06-27 15:42:25 +02:00
Eric Tuvesson
3fb3668fc3 feat: Allow relative git repository (#41) 2024-06-26 21:11:50 +02:00
Eric Tuvesson
fa282d6169 feat(runtime): Add "data-testid" attributes to UI nodes (#42) 2024-06-26 21:08:01 +02:00
61 changed files with 736 additions and 523 deletions

View File

@@ -1,15 +1,15 @@
name: Build noodl-editor
name: Build fluxscape-editor
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow from another workflow
workflow_call:
# release:
# types: [created]
jobs:
build_noodl_editor:
runs-on: ${{ matrix.os }}
@@ -32,11 +32,11 @@ jobs:
platform: linux-x64
steps:
- if: ${{ matrix.platform == 'darwin-arm64' }}
- if: ${{ matrix.platform == 'darwin-arm64' }}
name: Setup
uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: '3.11'
- name: Checkout
uses: actions/checkout@v4
@@ -72,6 +72,6 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: noodl-editor-${{ matrix.platform }}-${{ github.head_ref }}-${{ github.sha }}
name: fluxscape-editor-${{ matrix.platform }}-${{ github.head_ref }}-${{ github.sha }}
path: publish
retention-days: "12"
retention-days: '12'

View File

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

347
package-lock.json generated
View File

@@ -2849,9 +2849,9 @@
}
},
"node_modules/@electron/remote": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.1.tgz",
"integrity": "sha512-Lfxul2yBxL+FBVaKszNAkuUqSIDbUQ1I7BC394iRXyqA2XGz7im2bAxroNIM51jhySSPKUaOLHaFLxfV6pC9VQ==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.2.tgz",
"integrity": "sha512-EPwNx+nhdrTBxyCqXt/pftoQg/ybtWDW3DUWHafejvnB1ZGGfMpv6e15D8KeempocjXe78T7WreyGGb3mlZxdA==",
"peerDependencies": {
"electron": ">= 13.0.0"
}
@@ -25220,13 +25220,13 @@
}
},
"node_modules/electron": {
"version": "28.1.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-28.1.4.tgz",
"integrity": "sha512-WE6go611KOhtH6efRPMnVC7FE7DCKnQ3ZyHFeI1DbaCy8OU4UjZ8/CZGcuZmZgRdxSBEHoHdgaJkWRHZzF0FOg==",
"version": "31.3.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.3.1.tgz",
"integrity": "sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==",
"hasInstallScript": true,
"dependencies": {
"@electron/get": "^2.0.0",
"@types/node": "^18.11.18",
"@types/node": "^20.9.0",
"extract-zip": "^2.0.1"
},
"bin": {
@@ -25452,6 +25452,14 @@
"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": {
"version": "6.5.4",
"dev": true,
@@ -27203,6 +27211,10 @@
"react": "^15.0.2 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/fluxscape-editor": {
"resolved": "packages/noodl-editor",
"link": true
},
"node_modules/focus-lock": {
"version": "0.8.1",
"dev": true,
@@ -35443,10 +35455,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/noodl-editor": {
"resolved": "packages/noodl-editor",
"link": true
},
"node_modules/nopt": {
"version": "1.0.10",
"license": "MIT",
@@ -43191,6 +43199,11 @@
"version": "1.13.6",
"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": {
"version": "4.2.0",
"dev": true,
@@ -48967,9 +48980,10 @@
"dev": true
},
"packages/noodl-editor": {
"version": "1.0.0",
"name": "fluxscape-editor",
"version": "1.1.0",
"dependencies": {
"@electron/remote": "^2.1.1",
"@electron/remote": "^2.1.2",
"@jaames/iro": "^5.5.2",
"@microsoft/fetch-event-source": "^2.0.1",
"@noodl/git": "file:../noodl-git",
@@ -49025,7 +49039,7 @@
"babel-loader": "^8.2.4",
"concurrently": "^7.4.0",
"css-loader": "^6.7.1",
"electron": "28.1.4",
"electron": "31.3.1",
"electron-builder": "^24.9.1",
"file-loader": "^6.2.0",
"html-loader": "^3.1.0",
@@ -53375,9 +53389,9 @@
}
},
"@electron/remote": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.1.tgz",
"integrity": "sha512-Lfxul2yBxL+FBVaKszNAkuUqSIDbUQ1I7BC394iRXyqA2XGz7im2bAxroNIM51jhySSPKUaOLHaFLxfV6pC9VQ==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@electron/remote/-/remote-2.1.2.tgz",
"integrity": "sha512-EPwNx+nhdrTBxyCqXt/pftoQg/ybtWDW3DUWHafejvnB1ZGGfMpv6e15D8KeempocjXe78T7WreyGGb3mlZxdA==",
"requires": {}
},
"@electron/universal": {
@@ -74057,13 +74071,23 @@
}
},
"electron": {
"version": "28.1.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-28.1.4.tgz",
"integrity": "sha512-WE6go611KOhtH6efRPMnVC7FE7DCKnQ3ZyHFeI1DbaCy8OU4UjZ8/CZGcuZmZgRdxSBEHoHdgaJkWRHZzF0FOg==",
"version": "31.3.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.3.1.tgz",
"integrity": "sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==",
"requires": {
"@electron/get": "^2.0.0",
"@types/node": "^18.11.18",
"@types/node": "^20.9.0",
"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": {
@@ -75408,6 +75432,144 @@
"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": {
"version": "0.8.1",
"dev": true,
@@ -80983,144 +81145,6 @@
"version": "2.0.10",
"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": {
"version": "1.0.10",
"requires": {
@@ -86403,6 +86427,11 @@
"underscore": {
"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": {
"version": "4.2.0",
"dev": true

View File

@@ -12,7 +12,7 @@
"graph": "npx nx graph",
"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:editor": "lerna exec --scope noodl-editor -- npm run ci:build",
"ci:build:editor": "lerna exec --scope fluxscape-editor -- npm run ci:build",
"build:editor": "ts-node ./scripts/build-editor.ts",
"build:editor:_viewer": "ts-node ./scripts/noodl-editor/build-viewer.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",
"start:storybook": "lerna exec --scope @noodl/noodl-core-ui -- npm run start",
"start:viewer": "lerna run start --scope @noodl/noodl-viewer-react --stream",
"start:editor": "lerna run start --scope noodl-editor --stream",
"start:editor": "lerna run start --scope fluxscape-editor --stream",
"dev": "ts-node ./scripts/start.ts",
"start": "ts-node ./scripts/start.ts -- --build-viewer",
"test:editor": "ts-node ./scripts/test-editor.ts",
@@ -47,4 +47,4 @@
"npm": ">=6.0.0",
"node": ">=16.0.0 <=18"
}
}
}

View File

@@ -1,123 +1,128 @@
.Root {
border: none;
padding: 0;
background: transparent;
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
&.has-backdrop {
background-color: var(--theme-color-bg-1-transparent);
}
&.is-locking-scroll {
background-color: transparent;
}
&:not(.has-backdrop):not(.is-locking-scroll) {
pointer-events: none;
}
}
.VisibleDialog {
filter: drop-shadow(0 4px 15px var(--theme-color-bg-1-transparent-2));
box-shadow: 0 0 10px -5px var(--theme-color-bg-1-transparent-2);
position: absolute;
width: var(--width);
pointer-events: all;
.Root.is-centered & {
top: 50%;
left: 50%;
animation: enter-centered var(--speed-quick) var(--easing-base) both;
}
.Root:not(.is-centered) &.is-visible {
&.is-variant-default {
animation: enter var(--speed-quick) var(--easing-base) both;
}
&.is-variant-select {
transform: translate(var(--offsetX), var(--offsetY));
}
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--background);
border-radius: 2px;
overflow: hidden;
}
}
.Arrow {
position: absolute;
width: 0;
height: 0;
top: var(--arrow-top);
left: var(--arrow-left);
pointer-events: none;
&::after {
content: '';
display: block;
width: 11px;
height: 11px;
transform: translate(-50%, -50%) rotate(45deg);
background: var(--background);
}
&.is-contrast::after {
background: var(--backgroundContrast);
}
}
.Title {
background-color: var(--backgroundContrast);
padding: 12px;
}
.MeasuringContainer {
pointer-events: none;
height: 0;
overflow: visible;
opacity: 0;
}
.ChildContainer {
position: relative;
z-index: 1;
}
@keyframes enter {
from {
opacity: 0;
transform: translate(
calc(var(--animationStartOffsetX) + var(--offsetX)),
calc(var(--animationStartOffsetY) + var(--offsetY))
);
}
to {
opacity: 1;
transform: translate(var(--offsetX), var(--offsetY));
}
}
@keyframes enter-centered {
from {
opacity: 0;
transform: translate(-50%, calc(-50% + 16px));
}
to {
opacity: 1;
transform: translate(-50%, -50%);
}
}
.Root {
border: none;
padding: 0;
background: transparent;
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
&.is-hidden {
visibility: hidden;
pointer-events: none;
}
&.has-backdrop {
background-color: var(--theme-color-bg-1-transparent);
}
&.is-locking-scroll {
background-color: transparent;
}
&:not(.has-backdrop):not(.is-locking-scroll) {
pointer-events: none;
}
}
.VisibleDialog {
filter: drop-shadow(0 4px 15px var(--theme-color-bg-1-transparent-2));
box-shadow: 0 0 10px -5px var(--theme-color-bg-1-transparent-2);
position: absolute;
width: var(--width);
pointer-events: all;
.Root.is-centered & {
top: 50%;
left: 50%;
animation: enter-centered var(--speed-quick) var(--easing-base) both;
}
.Root:not(.is-centered) &.is-visible {
&.is-variant-default {
animation: enter var(--speed-quick) var(--easing-base) both;
}
&.is-variant-select {
transform: translate(var(--offsetX), var(--offsetY));
}
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--background);
border-radius: 2px;
overflow: hidden;
}
}
.Arrow {
position: absolute;
width: 0;
height: 0;
top: var(--arrow-top);
left: var(--arrow-left);
pointer-events: none;
&::after {
content: '';
display: block;
width: 11px;
height: 11px;
transform: translate(-50%, -50%) rotate(45deg);
background: var(--background);
}
&.is-contrast::after {
background: var(--backgroundContrast);
}
}
.Title {
background-color: var(--backgroundContrast);
padding: 12px;
}
.MeasuringContainer {
pointer-events: none;
height: 0;
overflow: visible;
opacity: 0;
}
.ChildContainer {
position: relative;
z-index: 1;
}
@keyframes enter {
from {
opacity: 0;
transform: translate(
calc(var(--animationStartOffsetX) + var(--offsetX)),
calc(var(--animationStartOffsetY) + var(--offsetY))
);
}
to {
opacity: 1;
transform: translate(var(--offsetX), var(--offsetY));
}
}
@keyframes enter-centered {
from {
opacity: 0;
transform: translate(-50%, calc(-50% + 16px));
}
to {
opacity: 1;
transform: translate(-50%, -50%);
}
}

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 540 KiB

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 175 B

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 408 B

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 220 B

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 360 B

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 KiB

View File

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

View File

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

View File

@@ -13,6 +13,7 @@ export default class SchemaHandler {
public dbCollections: TSFixme[];
public systemCollections: TSFixme[];
public configSchema: TSFixme;
public parseServerVersion: string;
constructor() {
EventDispatcher.instance.on(
@@ -119,6 +120,20 @@ export default class SchemaHandler {
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;
});
});
});
}
@@ -129,10 +144,20 @@ export default class SchemaHandler {
ProjectModel.instance.setMetaData('dbCollections', this.dbCollections);
ProjectModel.instance.setMetaData('systemCollections', this.systemCollections);
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 {
ProjectModel.instance.setMetaData('dbCollections', undefined);
ProjectModel.instance.setMetaData('systemCollections', undefined);
ProjectModel.instance.setMetaData('dbConfigSchema', undefined);
ProjectModel.instance.setMetaData('dbVersionMajor', undefined);
}
}
}

View File

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

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

View File

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

View File

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

View File

@@ -1,21 +1,24 @@
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 {
ProjectDiff,
ProjectDiffItem,
ProjectBasicDiffItem,
ArrayDiff,
diffProject
diffProject,
createEmptyArrayDiff
} 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 { 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{
export interface ProjectLocalDiff extends ProjectDiff {
baseProject: TSFixme; //Project model as an object from raw json
commitShaDiffedTo: string;
}
@@ -84,17 +87,49 @@ export function getFileStatusIconProps(status: FileStatusKind): Partial<ListItem
}
}
export async function doLocalDiff(repositoryPath: string, headCommitId: string): Promise<ProjectLocalDiff> {
const baseCommit = await getCommit(repositoryPath, headCommitId);
const baseProjectJson = await baseCommit.getFileAsString('project.json');
const baseProject = JSON.parse(baseProjectJson);
applyPatches(baseProject);
const diff = diffProject(baseProject, ProjectModel.instance.toJSON());
return {
...diff,
baseProject,
commitShaDiffedTo: headCommitId
};
export function getProjectFilePath(repositoryPath: string, projectPath: string) {
const relativePath = path.relative(repositoryPath, projectPath);
const projectFilePath = path.join(relativePath, 'project.json').replaceAll('\\', '/');
return projectFilePath;
}
export async function doLocalDiff(
repositoryPath: string,
projectPath: string,
headCommitId: string
): Promise<ProjectLocalDiff> {
const projectFilePath = getProjectFilePath(repositoryPath, projectPath);
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,6 +8,7 @@ import { Slot } from '@noodl-core-ui/types/global';
import { doLocalDiff, ProjectLocalDiff } from './DiffUtils';
import { useVersionControlFetch } from './fetch.context';
import { BranchStatus, IVersionControlContext } from './types';
import { ProjectModel } from '@noodl-models/projectmodel';
const VersionControlContext = createContext<IVersionControlContext>({
git: null,
@@ -57,7 +58,8 @@ export function VersionControlProvider({ git, children }: { git: Git; children:
(async () => {
const currentCommitSha = await git.getHeadCommitId();
if (currentCommitSha) {
const diff = await doLocalDiff(git.repositoryPath, currentCommitSha);
const projectPath = ProjectModel.instance._retainedProjectDirectory;
const diff = await doLocalDiff(git.repositoryPath, projectPath, currentCommitSha);
setLocalDiff(diff);
}
})();

View File

@@ -22,7 +22,11 @@ export async function open(basePath: string): Promise<string> {
// 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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,6 +9,8 @@ export interface SliderProps extends Noodl.ReactProps {
id: string;
enabled: boolean;
attrs: React.Attributes;
value: number;
min: number;
max: number;
@@ -103,6 +105,7 @@ export function Slider(props: SliderProps) {
const className = `ndl-controls-range2 ${instanceClassId} ${props.className ? props.className : ''} `;
const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {
...props.attrs,
id: props.id,
style: {
width: '100%',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,11 +30,24 @@ const ButtonNode = {
]
},
initialize() {
this.props.attrs = {};
this.props.layout = 'row'; //Used to tell child nodes what layout to expect
},
getReactComponent() {
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: {
backgroundColor: {
index: 100,

View File

@@ -31,6 +31,7 @@ const CheckBoxNode = {
]
},
initialize() {
this.props.attrs = {};
this.props.sizeMode = 'explicit';
this.props.id = 'input-' + guid();
this.props.checked = this._internal.checked = false;
@@ -94,6 +95,16 @@ const CheckBoxNode = {
this.flagOutputDirty('checked');
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: {

View File

@@ -31,6 +31,7 @@ const OptionsNode = {
]
},
initialize: function () {
this.props.attrs = {};
this._itemsChanged = () => {
this.forceUpdate();
};
@@ -90,6 +91,16 @@ const OptionsNode = {
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: {

View File

@@ -31,6 +31,7 @@ const RadioButtonNode = {
]
},
initialize() {
this.props.attrs = {};
this.props.sizeMode = 'explicit';
this.props.id = 'input-' + guid();
@@ -61,6 +62,16 @@ const RadioButtonNode = {
set(value) {
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: {

View File

@@ -27,6 +27,7 @@ const RangeNode = {
]
},
initialize() {
this.props.attrs = {};
this.props.sizeMode = 'contentHeight';
this.props.id = 'input-' + guid();
@@ -67,6 +68,16 @@ const RangeNode = {
set(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: {

View File

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

View File

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

View File

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

View File

@@ -1,18 +1,13 @@
'use strict';
const { Node, EdgeTriggeredInput } = require('@noodl/runtime');
const UserService = require('./userservice');
var LoginNodeDefinition = {
const LoginNodeDefinition = {
name: 'net.noodl.user.LogIn',
docs: 'https://docs.noodl.net/nodes/data/user/log-in',
displayNodeName: 'Log In',
category: 'Cloud Services',
color: 'data',
initialize: function () {
var internal = this._internal;
},
getInspectInfo() {},
outputs: {
success: {
type: 'signal',
@@ -28,7 +23,7 @@ var LoginNodeDefinition = {
type: 'string',
displayName: 'Error',
group: 'Error',
getter: function () {
getter() {
return this._internal.error;
}
}
@@ -37,7 +32,7 @@ var LoginNodeDefinition = {
login: {
displayName: 'Do',
group: 'Actions',
valueChangedToTrue: function () {
valueChangedToTrue() {
this.scheduleLogIn();
}
},
@@ -45,7 +40,7 @@ var LoginNodeDefinition = {
displayName: 'Username',
type: 'string',
group: 'General',
set: function (value) {
set(value) {
this._internal.username = value;
}
},
@@ -53,13 +48,13 @@ var LoginNodeDefinition = {
displayName: 'Password',
type: 'string',
group: 'General',
set: function (value) {
set(value) {
this._internal.password = value;
}
}
},
methods: {
setError: function (err) {
setError(err) {
this._internal.error = err;
this.flagOutputDirty('error');
this.sendSignalOnOutput('failure');
@@ -76,9 +71,7 @@ var LoginNodeDefinition = {
this.context.editorConnection.clearWarning(this.nodeScope.componentOwner.name, this.id, 'user-login-warning');
}
},
scheduleLogIn: function () {
const internal = this._internal;
scheduleLogIn() {
if (this.logInScheduled === true) return;
this.logInScheduled = true;
@@ -100,89 +93,7 @@ var 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 = {
node: LoginNodeDefinition,
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)
}
})*/
}
setup(_context, _graphModel) {}
};

View File

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

View File

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

View File

@@ -23,7 +23,7 @@ const ColumnsNode = {
]
},
initialize() {
initialize() { this.props.attrs = {};
this.props.layoutString = '1 2 1';
this.props.minWidth = 0;
this.props.marginX = 16;
@@ -62,6 +62,16 @@ 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();
}
}

View File

@@ -11,6 +11,7 @@ const GroupNode = {
groupPriority: ['General', 'Style', 'Events', 'Mounted', 'Hover Events', 'Pointer Events', 'Focus', 'Scroll']
},
initialize() {
this.props.attrs = {};
this._internal = {
scrollElementDuration: 500,
scrollIndexDuration: 500,
@@ -143,6 +144,16 @@ const GroupNode = {
valueChangedToTrue() {
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: {

View File

@@ -27,6 +27,7 @@ const ImageNode = {
]
},
initialize() {
this.props.attrs = {};
this.props.default = '';
},
getReactComponent() {
@@ -86,6 +87,16 @@ const ImageNode = {
this.props.dom.src = getAbsoluteUrl(url);
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: {
@@ -114,6 +125,12 @@ const ImageNode = {
propPath: 'dom',
type: 'signal',
group: 'Events'
},
onError: {
displayName: 'On Error',
propPath: 'dom',
type: 'signal',
group: 'Events'
}
}
};

View File

@@ -20,6 +20,9 @@ const TextNode = {
nodeDoubleClickAction: {
focusPort: 'text'
},
initialize() {
this.props.attrs = {};
},
getReactComponent() {
return Text;
},
@@ -135,6 +138,16 @@ const TextNode = {
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

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

View File

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

View File

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