@@ -4,7 +4,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- nightly
|
||||||
paths:
|
paths:
|
||||||
- "**"
|
- "**"
|
||||||
- "!.github/**"
|
- "!.github/**"
|
||||||
@@ -20,19 +20,19 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- app: frontend
|
- app: frontend
|
||||||
path: frontend
|
path: frontend
|
||||||
version: 2.0.0
|
version: nightly
|
||||||
experimental: true
|
experimental: true
|
||||||
- app: backend
|
- app: backend
|
||||||
path: backend
|
path: backend
|
||||||
version: 2.0.0
|
version: nightly
|
||||||
experimental: true
|
experimental: true
|
||||||
- app: orborus
|
- app: orborus
|
||||||
path: functions/onprem/orborus
|
path: functions/onprem/orborus
|
||||||
version: 2.0.0
|
version: nightly
|
||||||
experimental: true
|
experimental: true
|
||||||
- app: worker
|
- app: worker
|
||||||
path: functions/onprem/worker
|
path: functions/onprem/worker
|
||||||
version: 2.0.0
|
version: nightly
|
||||||
experimental: true
|
experimental: true
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -74,11 +74,8 @@ jobs:
|
|||||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||||
tags: |
|
tags: |
|
||||||
ghcr.io/shuffle/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
ghcr.io/shuffle/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
||||||
ghcr.io/shuffle/shuffle-${{ matrix.app }}:latest
|
|
||||||
${{ secrets.DOCKERHUB_USERNAME }}/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
${{ secrets.DOCKERHUB_USERNAME }}/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
||||||
${{ secrets.DOCKERHUB_USERNAME }}/shuffle-${{ matrix.app }}:latest
|
|
||||||
frikky/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
frikky/shuffle-${{ matrix.app }}:${{ matrix.version }}
|
||||||
frikky/shuffle-${{ matrix.app }}:latest
|
|
||||||
frikky/shuffle:${{ matrix.app }}
|
frikky/shuffle:${{ matrix.app }}
|
||||||
|
|
||||||
- name: Image digest
|
- name: Image digest
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ on:
|
|||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
branches:
|
branches:
|
||||||
- 2.0.0
|
- nightly
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Shuffle Automation
|
|||||||
|
|
||||||
[](https://github.com/Shuffle/Shuffle/actions/workflows/codeql-analysis.yml)
|
[](https://github.com/Shuffle/Shuffle/actions/workflows/codeql-analysis.yml)
|
||||||
[](https://github.com/Shuffle/Shuffle/actions/workflows/dockerbuild.yaml)
|
[](https://github.com/Shuffle/Shuffle/actions/workflows/dockerbuild.yaml)
|
||||||
|
[](https://console.aws.amazon.com/cloudformation/home?#/stacks/new?stackName=Shuffle-Instance&templateURL=https://shuffle-public-amis.s3.eu-north-1.amazonaws.com/template.yaml)
|
||||||
|
|
||||||
</h1><h4 align="center">
|
</h1><h4 align="center">
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ require (
|
|||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/h2non/filetype v1.1.3
|
github.com/h2non/filetype v1.1.3
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shuffle/shuffle-shared v0.6.90
|
github.com/shuffle/shuffle-shared v0.6.94
|
||||||
golang.org/x/crypto v0.31.0
|
golang.org/x/crypto v0.22.0
|
||||||
google.golang.org/api v0.176.1
|
google.golang.org/api v0.176.1
|
||||||
google.golang.org/grpc v1.63.2
|
google.golang.org/grpc v1.63.2
|
||||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||||
@@ -116,15 +116,15 @@ require (
|
|||||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.24.0 // indirect
|
||||||
golang.org/x/oauth2 v0.19.0 // indirect
|
golang.org/x/oauth2 v0.19.0 // indirect
|
||||||
golang.org/x/sync v0.10.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
golang.org/x/term v0.27.0 // indirect
|
golang.org/x/term v0.19.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
golang.org/x/tools v0.18.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c // indirect
|
||||||
|
|||||||
+18
-16
@@ -334,6 +334,8 @@ github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdR
|
|||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
|
github.com/shuffle/shuffle-shared v0.6.77 h1:KKtM50xW2DLuRHINxhp3uXrNH0AhiwkeiiU93a8fB3A=
|
||||||
|
github.com/shuffle/shuffle-shared v0.6.77/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
|
||||||
github.com/shuffle/shuffle-shared v0.6.90 h1:FzIYtEt44eWgEsW/9tj2ki7qq8FEm/HWXUok+THp72M=
|
github.com/shuffle/shuffle-shared v0.6.90 h1:FzIYtEt44eWgEsW/9tj2ki7qq8FEm/HWXUok+THp72M=
|
||||||
github.com/shuffle/shuffle-shared v0.6.90/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
|
github.com/shuffle/shuffle-shared v0.6.90/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
@@ -408,8 +410,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -438,8 +440,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -466,8 +468,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
|||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -484,8 +486,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -515,16 +517,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -536,8 +538,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
@@ -572,8 +574,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
|
|||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
frontend:
|
frontend:
|
||||||
image: ghcr.io/shuffle/shuffle-frontend:1.4.0
|
image: ghcr.io/shuffle/shuffle-frontend:1.4.2
|
||||||
container_name: shuffle-frontend
|
container_name: shuffle-frontend
|
||||||
hostname: shuffle-frontend
|
hostname: shuffle-frontend
|
||||||
ports:
|
ports:
|
||||||
@@ -14,7 +14,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
backend:
|
backend:
|
||||||
image: ghcr.io/shuffle/shuffle-backend:1.4.0
|
image: ghcr.io/shuffle/shuffle-backend:1.4.2
|
||||||
container_name: shuffle-backend
|
container_name: shuffle-backend
|
||||||
hostname: ${BACKEND_HOSTNAME}
|
hostname: ${BACKEND_HOSTNAME}
|
||||||
# Here for debugging:
|
# Here for debugging:
|
||||||
@@ -53,9 +53,9 @@ services:
|
|||||||
- SHUFFLE_PASS_WORKER_PROXY=${SHUFFLE_PASS_WORKER_PROXY}
|
- SHUFFLE_PASS_WORKER_PROXY=${SHUFFLE_PASS_WORKER_PROXY}
|
||||||
- SHUFFLE_PASS_APP_PROXY=${SHUFFLE_PASS_APP_PROXY}
|
- SHUFFLE_PASS_APP_PROXY=${SHUFFLE_PASS_APP_PROXY}
|
||||||
- SHUFFLE_STATS_DISABLED=true
|
- SHUFFLE_STATS_DISABLED=true
|
||||||
# - SHUFFLE_SWARM_CONFIG=run
|
- SHUFFLE_SWARM_CONFIG=run
|
||||||
- SHUFFLE_LOGS_DISABLED=true
|
- SHUFFLE_LOGS_DISABLED=true
|
||||||
- SHUFFLE_WORKER_IMAGE=ghcr.io/shuffle/shuffle-worker:1.4.0
|
- SHUFFLE_WORKER_IMAGE=ghcr.io/shuffle/shuffle-worker:1.4.2
|
||||||
env_file: .env
|
env_file: .env
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
security_opt:
|
security_opt:
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Stack,
|
Stack,
|
||||||
Avatar,
|
Avatar,
|
||||||
|
Skeleton,
|
||||||
|
Tooltip,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
@@ -22,8 +24,8 @@ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
|||||||
import LaunchIcon from '@mui/icons-material/Launch';
|
import LaunchIcon from '@mui/icons-material/Launch';
|
||||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||||
import { CloudDownloadOutlined } from '@mui/icons-material';
|
import { CloudDownloadOutlined } from '@mui/icons-material';
|
||||||
import { findSpecificApp } from './AppFramework';
|
import { findSpecificApp } from '../components/AppFramework.jsx';
|
||||||
import theme from "../theme";
|
import theme from "../theme.jsx";
|
||||||
import YAML from 'yaml';
|
import YAML from 'yaml';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
@@ -38,6 +40,7 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
const [inputUsecase, setInputUsecase] = useState({})
|
const [inputUsecase, setInputUsecase] = useState({})
|
||||||
const [latestUsecase, setLatestUsecase] = useState([])
|
const [latestUsecase, setLatestUsecase] = useState([])
|
||||||
const [foundAppUsecase, setFoundAppUsecase] = useState({})
|
const [foundAppUsecase, setFoundAppUsecase] = useState({})
|
||||||
|
const [usecaseLoading, setUsecaseLoading] = useState(false)
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const parseUsecase = (subcase) => {
|
const parseUsecase = (subcase) => {
|
||||||
const srcdata = findSpecificApp(frameworkData, subcase.type)
|
const srcdata = findSpecificApp(frameworkData, subcase.type)
|
||||||
@@ -142,6 +145,19 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
setLatestUsecase(newUsecases)
|
setLatestUsecase(newUsecases)
|
||||||
|
if (newUsecases?.length > 0) {
|
||||||
|
const foundCategory = newUsecases?.find((category) =>
|
||||||
|
category?.list?.some((subcase) => subcase?.srcapp === app?.name || subcase?.dstapp === app?.name)
|
||||||
|
);
|
||||||
|
|
||||||
|
const foundSubcase = foundCategory?.list?.find(
|
||||||
|
(subcase) => subcase?.srcapp === app?.name || subcase?.dstapp === app?.name
|
||||||
|
);
|
||||||
|
|
||||||
|
setFoundAppUsecase(foundSubcase);
|
||||||
|
}
|
||||||
|
setUsecaseLoading(false)
|
||||||
|
|
||||||
// Matching workflows with usecases
|
// Matching workflows with usecases
|
||||||
if (responseJson.success !== false) {
|
if (responseJson.success !== false) {
|
||||||
if (workflows !== undefined && workflows !== null && workflows.length > 0) {
|
if (workflows !== undefined && workflows !== null && workflows.length > 0) {
|
||||||
@@ -275,23 +291,12 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setUsecaseLoading(true)
|
||||||
getAvailableWorkflows()
|
getAvailableWorkflows()
|
||||||
getFramework()
|
getFramework()
|
||||||
}, [app])
|
}, [app])
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const foundCategory = latestUsecase?.find((category) =>
|
|
||||||
category?.list?.some((subcase) => subcase?.srcapp === app?.name || subcase?.dstapp === app?.name)
|
|
||||||
);
|
|
||||||
|
|
||||||
const foundSubcase = foundCategory?.list?.find(
|
|
||||||
(subcase) => subcase?.srcapp === app?.name || subcase?.dstapp === app?.name
|
|
||||||
);
|
|
||||||
|
|
||||||
setFoundAppUsecase(foundSubcase);
|
|
||||||
}, [latestUsecase])
|
|
||||||
|
|
||||||
const downloadApp = (inputdata) => {
|
const downloadApp = (inputdata) => {
|
||||||
const id = inputdata.id;
|
const id = inputdata.id;
|
||||||
|
|
||||||
@@ -389,9 +394,8 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
newAppname = newAppname?.replaceAll("_", " ");
|
newAppname = newAppname?.replaceAll("_", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
var canEditApp = userdata.admin === "true" || userdata?.id === app?.owner || app?.owner === "" || (userdata.admin === "true" && userdata.active_org.id === app?.reference_org) || !app?.generated
|
|
||||||
|
|
||||||
|
|
||||||
|
var canEditApp = userdata !== undefined && (userdata?.admin === "true" || userdata?.id === app?.owner || app?.owner === "" || (userdata?.admin === "true" && userdata?.active_org?.id === app?.reference_org)) || !app?.generated
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -501,6 +505,13 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
app?.private_id !== undefined &&
|
app?.private_id !== undefined &&
|
||||||
app?.private_id?.length > 0 &&
|
app?.private_id?.length > 0 &&
|
||||||
app?.generated ? (
|
app?.generated ? (
|
||||||
|
<Tooltip title="Download OpenAPI"
|
||||||
|
placement="top"
|
||||||
|
arrow
|
||||||
|
sx={{
|
||||||
|
fontFamily: theme?.typography?.fontFamily
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
@@ -522,7 +533,9 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CloudDownloadOutlined />
|
<CloudDownloadOutlined />
|
||||||
</Button>) : null}
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
@@ -655,6 +668,16 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
justifyContent: "start",
|
justifyContent: "start",
|
||||||
width: "100%"
|
width: "100%"
|
||||||
}}>
|
}}>
|
||||||
|
{usecaseLoading ? (
|
||||||
|
<Skeleton
|
||||||
|
variant="text"
|
||||||
|
width="55%"
|
||||||
|
sx={{
|
||||||
|
fontSize: "16px",
|
||||||
|
mb: "16px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<div style={{
|
<div style={{
|
||||||
fontFamily: theme?.typography?.fontFamily,
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
@@ -666,10 +689,11 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
(foundAppUsecase?.srcapp !== undefined && foundAppUsecase?.dstapp !== undefined) ? (
|
(foundAppUsecase?.srcapp !== undefined && foundAppUsecase?.dstapp !== undefined) ? (
|
||||||
"Connect " + foundAppUsecase?.srcapp?.replaceAll("_", " ") + " to " + foundAppUsecase?.dstapp?.replaceAll("_", " ")
|
"Connect " + foundAppUsecase?.srcapp?.replaceAll("_", " ") + " to " + foundAppUsecase?.dstapp?.replaceAll("_", " ")
|
||||||
) : (
|
) : (
|
||||||
"Connect " + app?.name + " to any tool"
|
"Connect " + app?.name.replaceAll("_", " ") + " to any tool"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
bgcolor: '#2F2F2F',
|
bgcolor: '#2F2F2F',
|
||||||
@@ -679,11 +703,19 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
mb: 3
|
mb: 3
|
||||||
}}>
|
}}>
|
||||||
|
{usecaseLoading ? (
|
||||||
|
<Stack direction="row" spacing={2} alignItems="center" sx={{ width: '100%' }}>
|
||||||
<Stack direction="row" spacing={-1}>
|
<Stack direction="row" spacing={-1}>
|
||||||
{
|
<Skeleton variant="circular" width={32} height={32} />
|
||||||
foundAppUsecase === undefined ? (
|
<Skeleton variant="circular" width={32} height={32} />
|
||||||
<Avatar sx={{ width: 32, height: 32, bgcolor: 'background.paper', border: 1, borderColor: 'divider' }}>
|
</Stack>
|
||||||
<Search sx={{ color: 'text.primary', zIndex: 10, fontSize: 18 }} />
|
<Skeleton variant="text" sx={{ flexGrow: 1 }} width={200} />
|
||||||
|
</Stack>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Stack direction="row" spacing={-1}>
|
||||||
|
{foundAppUsecase?.srcapp === undefined ? (
|
||||||
|
<Avatar sx={{ width: 32, height: 32, bgcolor: 'background.paper', border: 1, borderColor: 'divider' }} src={app?.image_url || app?.large_image}>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
) : (
|
) : (
|
||||||
<Avatar
|
<Avatar
|
||||||
@@ -697,10 +729,8 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
zIndex: 10
|
zIndex: 10
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)}
|
||||||
}
|
{foundAppUsecase?.dstapp === undefined ? (
|
||||||
{
|
|
||||||
foundAppUsecase === undefined ? (
|
|
||||||
<Avatar sx={{ width: 32, height: 32, bgcolor: 'background.paper', border: 1, borderColor: 'divider' }}>
|
<Avatar sx={{ width: 32, height: 32, bgcolor: 'background.paper', border: 1, borderColor: 'divider' }}>
|
||||||
<AddIcon sx={{ color: 'text.primary', zIndex: 10, fontSize: 18 }} />
|
<AddIcon sx={{ color: 'text.primary', zIndex: 10, fontSize: 18 }} />
|
||||||
</Avatar>
|
</Avatar>
|
||||||
@@ -716,12 +746,13 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
zIndex: 10
|
zIndex: 10
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
<Typography sx={{ ml: 2, fontSize: "16px", letterSpacing: "0.5px" }}>
|
<Typography sx={{ ml: 2, fontSize: "16px", letterSpacing: "0.5px" }}>
|
||||||
{foundAppUsecase?.name || "Search for a Usecase"}
|
{foundAppUsecase?.name || "Search for a Usecase"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -742,10 +773,13 @@ const AppModal = ({ open, onClose, app, globalUrl }) => {
|
|||||||
minWidth: '200px'
|
minWidth: '200px'
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/usecases2")
|
navigate("/usecases")
|
||||||
}}
|
}}
|
||||||
|
disabled={usecaseLoading}
|
||||||
>
|
>
|
||||||
Find a Usecase
|
{
|
||||||
|
(foundAppUsecase !== undefined && foundAppUsecase !== null && usecaseLoading === false) ? "See usecase" : "Find a Usecase"
|
||||||
|
}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -536,15 +536,16 @@ const AppSelection = props => {
|
|||||||
})}
|
})}
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
{
|
|
||||||
!isAppPage && (
|
|
||||||
<>
|
|
||||||
{!moreButton ? (
|
{!moreButton ? (
|
||||||
<div style={{ width: "100%", marginLeft: isMobile ? 80 : 200, marginBottom: 20, textAlign: isMobile ? "center" : null }}>
|
<div style={{ width: "100%", marginLeft: isMobile ? 80 : 200, marginBottom: 20, textAlign: isMobile ? "center" : null }}>
|
||||||
<Link style={{ color: "#FF8444" }} onClick={() => {
|
<Link style={{ color: "#FF8444" }} onClick={() => {
|
||||||
setMoreButton(true)
|
setMoreButton(true)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
if (isAppPage) {
|
||||||
|
navigate("/apps?tab=all_apps")
|
||||||
|
} else {
|
||||||
navigate("/welcome?tab=2")
|
navigate("/welcome?tab=2")
|
||||||
|
}
|
||||||
}, 250)
|
}, 250)
|
||||||
}}
|
}}
|
||||||
>See More Apps</Link>
|
>See More Apps</Link>
|
||||||
@@ -552,15 +553,14 @@ const AppSelection = props => {
|
|||||||
|
|
||||||
<div style={{ flexDirection: "row", width: isMobile ? 340 : null, textAlign: isMobile ? "center" : null }}>
|
<div style={{ flexDirection: "row", width: isMobile ? 340 : null, textAlign: isMobile ? "center" : null }}>
|
||||||
<Button variant="contained" type="submit" fullWidth style={bottomButtonStyle} onClick={() => {
|
<Button variant="contained" type="submit" fullWidth style={bottomButtonStyle} onClick={() => {
|
||||||
navigate("/usecases2")
|
navigate("/usecases")
|
||||||
|
if(!isAppPage) {
|
||||||
setActiveStep(2)
|
setActiveStep(2)
|
||||||
|
}
|
||||||
}}>
|
}}>
|
||||||
See usecases
|
See usecases
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -537,6 +537,7 @@ const CacheView = memo((props) => {
|
|||||||
padding: "15px 5px",
|
padding: "15px 5px",
|
||||||
maxHeight: 300,
|
maxHeight: 300,
|
||||||
verticalAlign: "middle",
|
verticalAlign: "middle",
|
||||||
|
maxWidth: 300,
|
||||||
}}
|
}}
|
||||||
primary={validate.valid ?
|
primary={validate.valid ?
|
||||||
<ReactJson
|
<ReactJson
|
||||||
|
|||||||
@@ -133,14 +133,18 @@ const DetectionExplorer = (props) => {
|
|||||||
|
|
||||||
const handleConnectClick = () => {
|
const handleConnectClick = () => {
|
||||||
if (detectionWorkflowId !== "") {
|
if (detectionWorkflowId !== "") {
|
||||||
|
console.log("Already have a workflow ID for this detection")
|
||||||
|
//toast.info(`Already have a detection workflow for ${detectionInfo?.category}`)
|
||||||
// FIXME: Show the Usecase UI for how to fix the workflow(s)
|
// FIXME: Show the Usecase UI for how to fix the workflow(s)
|
||||||
// Instead loading full workflow and showing it directly? Hmm
|
// Instead loading full workflow and showing it directly? Hmm
|
||||||
//toast.warn("Please reload the UI to load the detection status")
|
//toast.warn("Please reload the UI to load the detection status")
|
||||||
return
|
//return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDetectionActive) {
|
if (isDetectionActive) {
|
||||||
return
|
console.log("Already connected")
|
||||||
|
//toast.info(`Connected to ${detectionInfo?.category}`)
|
||||||
|
//return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (detectionInfo.category === undefined || detectionInfo.category === null) {
|
if (detectionInfo.category === undefined || detectionInfo.category === null) {
|
||||||
@@ -276,7 +280,7 @@ const DetectionExplorer = (props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" component="div">
|
<Typography variant="h6" component="div">
|
||||||
{detectionInfo?.title} {filteredRules === undefined || filteredRules === null ? null : `(${filteredRules?.length} rules)`}
|
{detectionInfo?.title} {filteredRules === undefined || filteredRules === null ? null : `(${filteredRules?.length} rule${filteredRules?.length > 1 ? "s" : ""})`}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<div style={{display: "flex", }}>
|
<div style={{display: "flex", }}>
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
Typography,
|
Typography,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
|
Checkbox,
|
||||||
|
Chip,
|
||||||
|
Menu,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -35,6 +38,7 @@ import {
|
|||||||
Publish as PublishIcon,
|
Publish as PublishIcon,
|
||||||
Clear as ClearIcon,
|
Clear as ClearIcon,
|
||||||
Add as AddIcon,
|
Add as AddIcon,
|
||||||
|
SelectAll,
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
|
|
||||||
import Dropzone from "../components/Dropzone.jsx";
|
import Dropzone from "../components/Dropzone.jsx";
|
||||||
@@ -61,6 +65,14 @@ const Files = memo((props) => {
|
|||||||
const [downloadBranch, setDownloadBranch] = React.useState("main");
|
const [downloadBranch, setDownloadBranch] = React.useState("main");
|
||||||
const [downloadFolder, setDownloadFolder] = React.useState("translation_standards");
|
const [downloadFolder, setDownloadFolder] = React.useState("translation_standards");
|
||||||
const [contentLoading, setContentLoading] = React.useState(false)
|
const [contentLoading, setContentLoading] = React.useState(false)
|
||||||
|
const [selectAllChecked, setSelectAllChecked] = React.useState(false)
|
||||||
|
const [selectedFiles, setSelectedFiles] = useState([]);
|
||||||
|
const [selectedFileId, setSelectedFileId] = useState([])
|
||||||
|
const [showFileCategoryPopup, setShowFileCategoryPopup] = useState(false)
|
||||||
|
const [updateToThisCategory, setUpdateToThisCategory] = useState("")
|
||||||
|
const [showDistributionPopup, setShowDistributionPopup] = useState(false)
|
||||||
|
const [selectedSubOrg, setSelectedSubOrg] = useState([])
|
||||||
|
const [fileIdSelectedForDistribution, setFileIdSelectedForDistribution] = useState("")
|
||||||
//const alert = useAlert();
|
//const alert = useAlert();
|
||||||
const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv", "log", "eml", "msg", "md", "xml", "sh", "bat", "ps1", "psm1", "psd1", "ps1xml", "pssc", "psc1", "response"]
|
const allowedFileTypes = ["txt", "py", "yaml", "yml","json", "html", "js", "csv", "log", "eml", "msg", "md", "xml", "sh", "bat", "ps1", "psm1", "psd1", "ps1xml", "pssc", "psc1", "response"]
|
||||||
var upload = "";
|
var upload = "";
|
||||||
@@ -80,6 +92,56 @@ const Files = memo((props) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeDistribution = (id, selectedSubOrg) => {
|
||||||
|
|
||||||
|
editFileConfig(id, "suborg_distribute", [...new Set(selectedSubOrg)])
|
||||||
|
}
|
||||||
|
|
||||||
|
const editFileConfig = (id, parentAction, selectedSubOrg) => {
|
||||||
|
const data = {
|
||||||
|
id: id,
|
||||||
|
action: parentAction !== undefined && parentAction !== null ? parentAction : "change_category",
|
||||||
|
selected_suborgs: selectedSubOrg,
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = globalUrl + "/api/v1/files/" + id + "/config";
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
mode: "cors",
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
credentials: "include",
|
||||||
|
crossDomain: true,
|
||||||
|
withCredentials: true,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) =>
|
||||||
|
response.json().then((responseJson) => {
|
||||||
|
if (responseJson["success"] === false) {
|
||||||
|
toast("Failed overwriting files");
|
||||||
|
} else {
|
||||||
|
toast("Successfully updated file!");
|
||||||
|
setTimeout(() => {
|
||||||
|
getFiles();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch((error) => {
|
||||||
|
toast("Err: " + error.toString());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileCheckboxChange = (index) => {
|
||||||
|
setSelectedFiles((prevSelected) => {
|
||||||
|
const updatedSelected = [...prevSelected];
|
||||||
|
updatedSelected[index] = !updatedSelected[index];
|
||||||
|
return updatedSelected;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const runUpdateText = (text) =>{
|
const runUpdateText = (text) =>{
|
||||||
fetch(`${globalUrl}/api/v1/files/${openFileId}/edit`, {
|
fetch(`${globalUrl}/api/v1/files/${openFileId}/edit`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
@@ -137,6 +199,7 @@ const Files = memo((props) => {
|
|||||||
if (responseJson.files !== undefined && responseJson.files !== null) {
|
if (responseJson.files !== undefined && responseJson.files !== null) {
|
||||||
setFiles(responseJson.files);
|
setFiles(responseJson.files);
|
||||||
setShowLoader(false)
|
setShowLoader(false)
|
||||||
|
setShowDistributionPopup(false)
|
||||||
} else if (responseJson.list !== undefined && responseJson.list !== null) {
|
} else if (responseJson.list !== undefined && responseJson.list !== null) {
|
||||||
// Set the "namespace" field in all items
|
// Set the "namespace" field in all items
|
||||||
if (namespace !== undefined && namespace !== null) {
|
if (namespace !== undefined && namespace !== null) {
|
||||||
@@ -152,6 +215,7 @@ const Files = memo((props) => {
|
|||||||
} else {
|
} else {
|
||||||
setFiles([]);
|
setFiles([]);
|
||||||
setShowLoader(false)
|
setShowLoader(false)
|
||||||
|
setShowDistributionPopup(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (namespace === undefined || namespace === null || namespace === "default") {
|
if (namespace === undefined || namespace === null || namespace === "default") {
|
||||||
@@ -256,7 +320,7 @@ const Files = memo((props) => {
|
|||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
minWidth: "800px",
|
minWidth: "800px",
|
||||||
minHeight: "320px",
|
minHeight: "320px",
|
||||||
overflow: "hidden",
|
overflow: "auto",
|
||||||
'& .MuiDialogContent-root': {
|
'& .MuiDialogContent-root': {
|
||||||
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
},
|
},
|
||||||
@@ -400,6 +464,127 @@ const Files = memo((props) => {
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
: null
|
: null
|
||||||
|
|
||||||
|
const handleSelectSubOrg = (id, action) => {
|
||||||
|
if (action === "all") {
|
||||||
|
const childOrgs = userdata.orgs.filter(
|
||||||
|
(data) => data.creator_org === userdata.active_org.id
|
||||||
|
);
|
||||||
|
setSelectedSubOrg((prev) => {
|
||||||
|
if (prev.length === childOrgs.length) {
|
||||||
|
// If all child orgs are already selected, clear the selection
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
// Otherwise, select all child org IDs
|
||||||
|
return childOrgs.map((data) => data.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (action === "none") {
|
||||||
|
setSelectedSubOrg([]);
|
||||||
|
} else {
|
||||||
|
setSelectedSubOrg((prev) => {
|
||||||
|
if (prev.includes(id)) {
|
||||||
|
return prev.filter((data) => data !== id);
|
||||||
|
} else {
|
||||||
|
return [...prev, id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileDistributionModal = showDistributionPopup ? (
|
||||||
|
<Dialog
|
||||||
|
open={showDistributionPopup}
|
||||||
|
onClose={() => setShowDistributionPopup(false)}
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
borderRadius: theme?.palette?.DialogStyle?.borderRadius,
|
||||||
|
border: theme?.palette?.DialogStyle?.border,
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
zIndex: 1000,
|
||||||
|
minWidth: "600px",
|
||||||
|
minHeight: "320px",
|
||||||
|
overflow: "auto",
|
||||||
|
'& .MuiDialogContent-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
'& .MuiDialogTitle-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
'& .MuiDialogActions-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogTitle>
|
||||||
|
<div style={{ color: "rgba(255,255,255,0.9)" }}>
|
||||||
|
Select sub-org to distribute files
|
||||||
|
</div>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent style={{ color: "rgba(255,255,255,0.65)" }}>
|
||||||
|
<MenuItem value="none" onClick={()=> {handleSelectSubOrg(null, "none")}}>None</MenuItem>
|
||||||
|
<MenuItem value="all" onClick={()=> {handleSelectSubOrg(null, "all")}}>All</MenuItem>
|
||||||
|
{userdata.orgs.map((data, index) => {
|
||||||
|
if (data.creator_org !== userdata.active_org.id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imagesize = 22;
|
||||||
|
const imageStyle = {
|
||||||
|
width: imagesize,
|
||||||
|
height: imagesize,
|
||||||
|
pointerEvents: "none",
|
||||||
|
marginRight: 10,
|
||||||
|
marginLeft: data.id === userdata.active_org.id ? 0 : 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
const image = data.image === "" ? (
|
||||||
|
<img alt={data.name} src={theme.palette.defaultImage} style={imageStyle} />
|
||||||
|
) : (
|
||||||
|
<img alt={data.name} src={data.image} style={imageStyle} />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={index}
|
||||||
|
value={data.id}
|
||||||
|
onClick={() => handleSelectSubOrg(data.id)}
|
||||||
|
style={{ display: "flex", alignItems: "center" }}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={selectedSubOrg.includes(data.id)}
|
||||||
|
/>
|
||||||
|
{image}
|
||||||
|
<span style={{ marginLeft: 8 }}>{data.name}</span>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div style={{ display: "flex", marginTop: 20 }}>
|
||||||
|
<Button
|
||||||
|
style={{ borderRadius: "2px", textTransform: 'none', fontSize:16, color: "#ff8544" }}
|
||||||
|
onClick={() => setShowDistributionPopup(false)}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
style={{ borderRadius: "2px", textTransform: 'none', fontSize:16, color: "#1a1a1a", backgroundColor: "#ff8544", marginLeft: 10 }}
|
||||||
|
onClick={() => {
|
||||||
|
changeDistribution(fileIdSelectedForDistribution, selectedSubOrg);
|
||||||
|
}}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
): null
|
||||||
|
|
||||||
const deleteFile = (file) => {
|
const deleteFile = (file) => {
|
||||||
fetch(globalUrl + "/api/v1/files/" + file.id, {
|
fetch(globalUrl + "/api/v1/files/" + file.id, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
@@ -636,7 +821,7 @@ const Files = memo((props) => {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getFiles()
|
getFiles()
|
||||||
}, 2500);
|
}, 3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadFile = (e) => {
|
const uploadFile = (e) => {
|
||||||
@@ -649,6 +834,68 @@ const Files = memo((props) => {
|
|||||||
uploadFiles(files);
|
uploadFiles(files);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleUpdateFileCategory = (namespace) => {
|
||||||
|
|
||||||
|
if (selectedFiles.length === 0 && !selectAllChecked) {
|
||||||
|
toast("Please select files to update category")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namespace === undefined || namespace === null || namespace === "") {
|
||||||
|
toast("Please select a category to update files to")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = globalUrl + `/api/v1/files/namespaces/${namespace}/share`
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
SelectedFiles: selectedFileId,
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowLoader(true)
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
mode: "cors",
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
credentials: "include",
|
||||||
|
crossDomain: true,
|
||||||
|
withCredentials: true,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) =>
|
||||||
|
response.json().then((responseJson) => {
|
||||||
|
if (responseJson["success"] === false) {
|
||||||
|
toast("Failed overwriting files");
|
||||||
|
} else {
|
||||||
|
setSelectAllChecked(false)
|
||||||
|
setSelectedFiles([])
|
||||||
|
setSelectedFileId([])
|
||||||
|
setShowFileCategoryPopup(false)
|
||||||
|
setSelectedCategory(namespace)
|
||||||
|
setTimeout(() => {
|
||||||
|
getFiles();
|
||||||
|
toast("Successfully updated file!");
|
||||||
|
if (window.location.search.includes("category=")) {
|
||||||
|
const newurl = window.location.href.replace(/category=[^&]+/, `category=${namespace}`)
|
||||||
|
window.history.pushState({ path: newurl }, "", newurl)
|
||||||
|
} else {
|
||||||
|
window.history.pushState({ path: window.location.href }, "", `${window.location.href}&category=${namespace}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.catch((error) => {
|
||||||
|
toast("Err: " + error.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropzone
|
<Dropzone
|
||||||
style={{
|
style={{
|
||||||
@@ -659,6 +906,7 @@ const Files = memo((props) => {
|
|||||||
}}
|
}}
|
||||||
onDrop={uploadFile}
|
onDrop={uploadFile}
|
||||||
>
|
>
|
||||||
|
{fileDistributionModal}
|
||||||
<div style={{width: "100%", minHeight: 1100, boxSizing: 'border-box', padding: "27px 10px 19px 27px", height:"100%", backgroundColor: '#212121',borderTopRightRadius: '8px', borderBottomRightRadius: 8, borderLeft: "1px solid #494949", }}>
|
<div style={{width: "100%", minHeight: 1100, boxSizing: 'border-box', padding: "27px 10px 19px 27px", height:"100%", backgroundColor: '#212121',borderTopRightRadius: '8px', borderBottomRightRadius: 8, borderLeft: "1px solid #494949", }}>
|
||||||
|
|
||||||
<div style={{height: "100%", maxHeight: 1700,overflowY: 'auto', scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin'}}>
|
<div style={{height: "100%", maxHeight: 1700,overflowY: 'auto', scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin'}}>
|
||||||
@@ -739,14 +987,19 @@ const Files = memo((props) => {
|
|||||||
}}
|
}}
|
||||||
value={selectedCategory}
|
value={selectedCategory}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
|
if (selectAllChecked || selectedFiles.length > 0) {
|
||||||
|
setUpdateToThisCategory(event.target.value)
|
||||||
|
setShowFileCategoryPopup(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
setSelectedCategory(event.target.value)
|
setSelectedCategory(event.target.value)
|
||||||
|
|
||||||
if (event.target.value === "all" || event.target.value === "default") {
|
if (event.target.value === "all" || event.target.value === "default") {
|
||||||
getFiles()
|
getFiles()
|
||||||
} else {
|
} else {
|
||||||
getFiles(event.target.value)
|
getFiles(event.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add it to the url as a query
|
// Add it to the url as a query
|
||||||
if (window.location.search.includes("category=")) {
|
if (window.location.search.includes("category=")) {
|
||||||
const newurl = window.location.href.replace(/category=[^&]+/, `category=${event.target.value}`)
|
const newurl = window.location.href.replace(/category=[^&]+/, `category=${event.target.value}`)
|
||||||
@@ -768,14 +1021,41 @@ const Files = memo((props) => {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
|
<Dialog
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
borderRadius: theme?.palette?.DialogStyle?.borderRadius,
|
||||||
|
border: theme?.palette?.DialogStyle?.border,
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
zIndex: 1000,
|
||||||
|
'& .MuiDialogContent-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
'& .MuiDialogTitle-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
'& .MuiDialogActions-root': {
|
||||||
|
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}} open={showFileCategoryPopup} onClose={() => setShowFileCategoryPopup(false)}>
|
||||||
|
<DialogTitle>File Categories</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
Please note that your selected files ({selectedFileId?.length}) will be moved to the <kbd>{updateToThisCategory}</kbd> category.
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setShowFileCategoryPopup(false)} style={{fontSize: 16, textTransform: 'none'}}>Close</Button>
|
||||||
|
<Button onClick={() => handleUpdateFileCategory(updateToThisCategory)} style={{fontSize: 16, textTransform: 'none', color: "#1a1a1a", backgroundColor: "#ff8544"}}>Update</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
) : null}
|
) : null}
|
||||||
<div style={{display: "inline-flex", position:"relative", top: 8}}>
|
<div style={{display: "inline-flex", position:"relative", top: 8}}>
|
||||||
{renderTextBox ?
|
{renderTextBox ?
|
||||||
|
|
||||||
<Tooltip title={"Close"} style={{}} aria-label={""}>
|
<Tooltip title={"Close"} style={{}} aria-label={""}>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 5, marginRight: 15 }}
|
style={{ marginLeft: 5, marginRight: 15, height: 35, borderRadius: 4, backgroundColor: "#494949", textTransform: 'none', fontSize: 16, color: "#f1f1f1" }}
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setRenderTextBox(false);
|
setRenderTextBox(false);
|
||||||
@@ -803,10 +1083,24 @@ const Files = memo((props) => {
|
|||||||
{renderTextBox && <TextField
|
{renderTextBox && <TextField
|
||||||
onKeyPress={(event)=>{
|
onKeyPress={(event)=>{
|
||||||
handleKeyDown(event);
|
handleKeyDown(event);
|
||||||
|
if(event.key === 'Enter' && selectedFileId.length > 0){
|
||||||
|
setShowFileCategoryPopup(true)
|
||||||
|
setUpdateToThisCategory(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
width: 200,
|
||||||
|
marginTop: 0,
|
||||||
}}
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
|
height: 35,
|
||||||
|
fontSize: 16,
|
||||||
|
borderRadius: 4,
|
||||||
|
paddingTop: 0,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -816,7 +1110,6 @@ const Files = memo((props) => {
|
|||||||
defaultValue={""}
|
defaultValue={""}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>}</div>
|
/>}</div>
|
||||||
|
|
||||||
<ShuffleCodeEditor
|
<ShuffleCodeEditor
|
||||||
isCloud={isCloud}
|
isCloud={isCloud}
|
||||||
expansionModalOpen={openEditor}
|
expansionModalOpen={openEditor}
|
||||||
@@ -852,17 +1145,57 @@ const Files = memo((props) => {
|
|||||||
tableLayout: "auto",
|
tableLayout: "auto",
|
||||||
display: "table",
|
display: "table",
|
||||||
minWidth: 800,
|
minWidth: 800,
|
||||||
overflowX: "auto"
|
overflowX: "auto",
|
||||||
|
paddingBottom: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListItem style={{width:isSelectedFiles?"100%":null, borderBottom:isSelectedFiles?"1px solid #494949":null, display: 'table-row'}}>
|
<ListItem
|
||||||
{["Name", "Workflow", "Md5", "Status", "Filesize", "Actions"].map((header, index) => (
|
style={{
|
||||||
|
borderBottom: "1px solid #494949" ,
|
||||||
|
display: "table-row"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
<Tooltip title={"Select all files"} style={{}} aria-label={""}>
|
||||||
|
<Checkbox
|
||||||
|
sx={{padding: 0}}
|
||||||
|
onChange={() => {
|
||||||
|
setSelectAllChecked((prev) => !prev);
|
||||||
|
setSelectedFiles((prev) => {
|
||||||
|
if (prev.length === files.length) {
|
||||||
|
return []
|
||||||
|
} else {
|
||||||
|
return files.map((_, index) => !prev.includes(index))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (selectAllChecked) {
|
||||||
|
setSelectedFileId([])
|
||||||
|
} else {
|
||||||
|
setSelectedFileId(
|
||||||
|
files
|
||||||
|
.filter((file) => file.namespace === selectedCategory)
|
||||||
|
.map((file) => file.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tooltip>,
|
||||||
|
"Name",
|
||||||
|
"Workflow",
|
||||||
|
"Md5",
|
||||||
|
"Status",
|
||||||
|
"Filesize",
|
||||||
|
"Actions",
|
||||||
|
"Distribution"
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((header, index) => (
|
||||||
<ListItemText
|
<ListItemText
|
||||||
key={index}
|
key={index}
|
||||||
primary={header}
|
primary={header}
|
||||||
style={{
|
style={{
|
||||||
display: "table-cell",
|
display: "table-cell",
|
||||||
padding: index === 0 ? "0px 8px 8px 15px": "0px 8px 8px 8px",
|
padding: index === 0 ? "0px 8px 8px 15px" : "0px 8px 8px 8px",
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
textOverflow: "ellipsis",
|
textOverflow: "ellipsis",
|
||||||
borderBottom: "1px solid #494949",
|
borderBottom: "1px solid #494949",
|
||||||
@@ -870,7 +1203,7 @@ const Files = memo((props) => {
|
|||||||
}}
|
}}
|
||||||
primaryTypographyProps={{
|
primaryTypographyProps={{
|
||||||
style: {
|
style: {
|
||||||
paddingLeft: 10,
|
paddingLeft: 10
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -885,7 +1218,7 @@ const Files = memo((props) => {
|
|||||||
backgroundColor: "#212121",
|
backgroundColor: "#212121",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Array(6)
|
{Array(8)
|
||||||
.fill()
|
.fill()
|
||||||
.map((_, colIndex) => (
|
.map((_, colIndex) => (
|
||||||
<ListItemText
|
<ListItemText
|
||||||
@@ -928,7 +1261,7 @@ const Files = memo((props) => {
|
|||||||
if (index % 2 === 0) {
|
if (index % 2 === 0) {
|
||||||
bgColor = isSelectedFiles ? "#1A1A1A":"#1f2023";
|
bgColor = isSelectedFiles ? "#1A1A1A":"#1f2023";
|
||||||
}
|
}
|
||||||
|
const isDistributed = file?.suborg_distribution?.length > 0 ? true : false;
|
||||||
const filenamesplit = file.filename.split(".")
|
const filenamesplit = file.filename.split(".")
|
||||||
const iseditable = file.filesize < 2000000 && file.status === "active" && allowedFileTypes.includes(filenamesplit[filenamesplit.length-1])
|
const iseditable = file.filesize < 2000000 && file.status === "active" && allowedFileTypes.includes(filenamesplit[filenamesplit.length-1])
|
||||||
return (
|
return (
|
||||||
@@ -953,6 +1286,26 @@ const Files = memo((props) => {
|
|||||||
primary={new Date(file.updated_at * 1000).toISOString()}
|
primary={new Date(file.updated_at * 1000).toISOString()}
|
||||||
/>
|
/>
|
||||||
*/}
|
*/}
|
||||||
|
<ListItemText
|
||||||
|
style={{
|
||||||
|
display: 'table-cell',
|
||||||
|
overflow: "hidden",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
style={{ padding: 0 }}
|
||||||
|
disabled={file.org_id !== selectedOrganization.id}
|
||||||
|
checked={!!selectedFiles[index] || selectAllChecked}
|
||||||
|
onChange={() => {handleFileCheckboxChange(index); setSelectedFileId(prev => {
|
||||||
|
if (prev.includes(file.id)) {
|
||||||
|
return prev.filter((item) => item !== file.id)
|
||||||
|
} else {
|
||||||
|
return [...prev, file.id]
|
||||||
|
}
|
||||||
|
})}}
|
||||||
|
/>
|
||||||
|
</ListItemText>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{
|
primaryTypographyProps={{
|
||||||
style: {
|
style: {
|
||||||
@@ -1064,7 +1417,7 @@ const Files = memo((props) => {
|
|||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={!iseditable}
|
disabled={!iseditable || file.org_id !== selectedOrganization.id}
|
||||||
style = {{padding: "6px", }}
|
style = {{padding: "6px", }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenEditor(true)
|
setOpenEditor(true)
|
||||||
@@ -1137,7 +1490,6 @@ const Files = memo((props) => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
style = {{padding: "6px"}}
|
style = {{padding: "6px"}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log("file is : ", file)
|
|
||||||
navigator.clipboard.writeText(file.id);
|
navigator.clipboard.writeText(file.id);
|
||||||
document.execCommand("copy");
|
document.execCommand("copy");
|
||||||
|
|
||||||
@@ -1154,7 +1506,7 @@ const Files = memo((props) => {
|
|||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={file.status !== "active"}
|
disabled={file.status !== "active" || file.org_id !== selectedOrganization.id}
|
||||||
style={{ padding: "6px" }}
|
style={{ padding: "6px" }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
deleteFile(file);
|
deleteFile(file);
|
||||||
@@ -1166,7 +1518,7 @@ const Files = memo((props) => {
|
|||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
style={{
|
style={{
|
||||||
stroke: file.status === "active" ? "#fd4c62" : "#c8c8c8",
|
stroke: file.status === "active" && file.org_id === selectedOrganization.id ? "#fd4c62" : "#c8c8c8",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
@@ -1192,6 +1544,46 @@ const Files = memo((props) => {
|
|||||||
// overflow: "hidden",
|
// overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<ListItemText primaryTypographyProps={{
|
||||||
|
style: {
|
||||||
|
padding: 8
|
||||||
|
}
|
||||||
|
}} style={{ display: "table-cell", textAlign: 'center', verticalAlign: 'middle'}} >
|
||||||
|
{selectedOrganization.id !== undefined && file?.org_id !== selectedOrganization.id ?
|
||||||
|
<Tooltip
|
||||||
|
title="Parent organization controlled file. You can use, but not modify this file. Contact an admin of your parent organization if you need changes to this."
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<Chip
|
||||||
|
label={"Parent"}
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{display: "table-cell",}}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
:
|
||||||
|
<Tooltip
|
||||||
|
title="Distributed to sub-organizations. This means the sub organizations can use this file, but can not modify it."
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
disabled={selectedOrganization.creator_org !== undefined && selectedOrganization.creator_org !== null && selectedOrganization.creator_org !== "" ? true : false}
|
||||||
|
checked={isDistributed}
|
||||||
|
style={{ }}
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
setShowDistributionPopup(true)
|
||||||
|
if(file?.suborg_distribution?.length > 0){
|
||||||
|
setSelectedSubOrg(file.suborg_distribution)
|
||||||
|
}else{
|
||||||
|
setSelectedSubOrg([])
|
||||||
|
}
|
||||||
|
setFileIdSelectedForDistribution(file.id)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const {setLeftSideBarOpenByClick, leftSideBarOpenByClick, setSearchBarModalOpen, searchBarModalOpen} = useContext(Context);
|
const {setLeftSideBarOpenByClick, leftSideBarOpenByClick, setSearchBarModalOpen, searchBarModalOpen} = useContext(Context);
|
||||||
|
|
||||||
const [expandLeftNav, setExpandLeftNav] = useState(false);
|
const [expandLeftNav, setExpandLeftNav] = useState(false);
|
||||||
const [activeOrgName, setActiveOrgName] = useState(
|
const [activeOrgName, setActiveOrgName] = useState(
|
||||||
userdata?.active_org?.name || "Select Organziation"
|
userdata?.active_org?.name || "Select Organziation"
|
||||||
@@ -261,17 +262,20 @@ useEffect(() => {
|
|||||||
},[currentPath]);
|
},[currentPath]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
UpdateTabStatus();
|
UpdateTabStatus()
|
||||||
const expandLeftNav1 = localStorage.getItem("expandLeftNav");
|
|
||||||
|
const expandLeftNav1 = localStorage.getItem("expandLeftNav")
|
||||||
if (expandLeftNav1 === "false") {
|
if (expandLeftNav1 === "false") {
|
||||||
setLeftSideBarOpenByClick(false);
|
setLeftSideBarOpenByClick(false)
|
||||||
setLeftSideBarOpenByClick(false);
|
|
||||||
} else {
|
} else {
|
||||||
setLeftSideBarOpenByClick(true);
|
const currentLocation = window?.location?.pathname
|
||||||
setLeftSideBarOpenByClick(true);
|
if (currentLocation?.includes('/workflows/')) {
|
||||||
setExpandLeftNav(true);
|
} else {
|
||||||
|
setLeftSideBarOpenByClick(true)
|
||||||
|
setExpandLeftNav(true)
|
||||||
}
|
}
|
||||||
}, []);
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const getAvailableWorkflows = useCallback((amount) => {
|
const getAvailableWorkflows = useCallback((amount) => {
|
||||||
|
|
||||||
@@ -533,7 +537,7 @@ useEffect(() => {
|
|||||||
<Divider style={{ marginBottom: 10, }} />
|
<Divider style={{ marginBottom: 10, }} />
|
||||||
|
|
||||||
<Typography color="textSecondary" align="center" style={{ marginTop: 5, marginBottom: 5, fontSize: 18 }}>
|
<Typography color="textSecondary" align="center" style={{ marginTop: 5, marginBottom: 5, fontSize: 18 }}>
|
||||||
Version: 2.0.0-beta
|
Version: 2.0.0-rc2
|
||||||
</Typography>
|
</Typography>
|
||||||
</Menu>
|
</Menu>
|
||||||
</span>
|
</span>
|
||||||
@@ -591,6 +595,10 @@ useEffect(() => {
|
|||||||
org_id: orgId,
|
org_id: orgId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (userdata?.active_org?.id === orgId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
localStorage.setItem("globalUrl", "");
|
localStorage.setItem("globalUrl", "");
|
||||||
localStorage.setItem("getting_started_sidebar", "open");
|
localStorage.setItem("getting_started_sidebar", "open");
|
||||||
|
|
||||||
@@ -662,7 +670,8 @@ useEffect(() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getRegionTag = (region_url) => {
|
const getRegionTag = (region_url) => {
|
||||||
let regiontag = "UK";
|
//let regiontag = "UK";
|
||||||
|
let regiontag = "EU";
|
||||||
if (
|
if (
|
||||||
region_url !== undefined &&
|
region_url !== undefined &&
|
||||||
region_url !== null &&
|
region_url !== null &&
|
||||||
@@ -676,7 +685,7 @@ useEffect(() => {
|
|||||||
if (regiontag === "california") {
|
if (regiontag === "california") {
|
||||||
regiontag = "US";
|
regiontag = "US";
|
||||||
} else if (regiontag === "frankfurt") {
|
} else if (regiontag === "frankfurt") {
|
||||||
regiontag = "EU";
|
regiontag = "EU-2";
|
||||||
} else if (regiontag === "ca"){
|
} else if (regiontag === "ca"){
|
||||||
regiontag = "CA";
|
regiontag = "CA";
|
||||||
}
|
}
|
||||||
@@ -764,11 +773,18 @@ useEffect(() => {
|
|||||||
"UK": "gb"
|
"UK": "gb"
|
||||||
};
|
};
|
||||||
|
|
||||||
region = regionMapping[region_url] || "gb";
|
region = regionMapping[region_url] || "eu";
|
||||||
|
|
||||||
return `https://flagcdn.com/48x36/${region}.png`;
|
return `https://flagcdn.com/48x36/${region}.png`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (window?.location?.pathname?.includes("/workflows/")) {
|
||||||
|
setExpandLeftNav(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [window?.location?.pathname]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -785,6 +801,18 @@ useEffect(() => {
|
|||||||
zoom: 0.8,
|
zoom: 0.8,
|
||||||
height: "calc((100vh - 32px)*1.2)",
|
height: "calc((100vh - 32px)*1.2)",
|
||||||
}}
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
if (window?.location?.pathname?.includes("/workflows/")) {
|
||||||
|
setExpandLeftNav(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseOver={() => {
|
||||||
|
if (window?.location?.pathname?.includes("/workflows/")) {
|
||||||
|
setExpandLeftNav(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{modalView}
|
{modalView}
|
||||||
<Box
|
<Box
|
||||||
@@ -905,7 +933,7 @@ useEffect(() => {
|
|||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<kbd>Ctrl</kbd>/<kbd>Cmd</kbd>+<kbd>K</kbd>
|
<kbd>Ctrl</kbd>+<kbd>K</kbd>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
disableUnderline: true,
|
disableUnderline: true,
|
||||||
@@ -1153,17 +1181,14 @@ useEffect(() => {
|
|||||||
>
|
>
|
||||||
<span style={{ display: "inline-block", width: "100%" }}>
|
<span style={{ display: "inline-block", width: "100%" }}>
|
||||||
<Link
|
<Link
|
||||||
to={userdata?.support ? "/dashboards/security" : "#"}
|
to={"#"}
|
||||||
style={{
|
style={{
|
||||||
...hrefStyle,
|
...hrefStyle,
|
||||||
pointerEvents: userdata?.support ? "auto" : "none",
|
pointerEvents: "auto",
|
||||||
cursor: "not-allowed",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
disabled={true}
|
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (!userdata?.support) return;
|
|
||||||
setOpenSecurityTab(true);
|
setOpenSecurityTab(true);
|
||||||
setOpenautomateTab(false);
|
setOpenautomateTab(false);
|
||||||
setCurrentOpenTab("security");
|
setCurrentOpenTab("security");
|
||||||
@@ -1171,21 +1196,12 @@ useEffect(() => {
|
|||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
...ButtonStyle,
|
...ButtonStyle,
|
||||||
backgroundColor:
|
|
||||||
((currentOpenTab === "security" && currentPath.includes("/security")) ||
|
|
||||||
(!expandLeftNav &&
|
|
||||||
(currentPath.includes("detections") || currentPath.includes("response"))))
|
|
||||||
? "#2f2f2f"
|
|
||||||
: "transparent",
|
|
||||||
cursor: userdata?.support ? "pointer" : "not-allowed",
|
|
||||||
}}
|
}}
|
||||||
onMouseOver={(event)=>{
|
onMouseOver={(event)=>{
|
||||||
event.currentTarget.style.backgroundColor = "#2f2f2f";
|
event.currentTarget.style.backgroundColor = "#2f2f2f";
|
||||||
}}
|
}}
|
||||||
onMouseOut={(event)=>{
|
onMouseOut={(event)=>{
|
||||||
event.currentTarget.style.backgroundColor = ((currentOpenTab === "security" && currentPath.includes("/security")) ||
|
event.currentTarget.style.backgroundColor = currentOpenTab === "security"
|
||||||
(!expandLeftNav &&
|
|
||||||
(currentPath.includes("detections") || currentPath.includes("response"))))
|
|
||||||
? "#2f2f2f"
|
? "#2f2f2f"
|
||||||
: "transparent";
|
: "transparent";
|
||||||
}}
|
}}
|
||||||
@@ -1203,14 +1219,12 @@ useEffect(() => {
|
|||||||
display: expandLeftNav ? "inline" : "none",
|
display: expandLeftNav ? "inline" : "none",
|
||||||
marginRight: "auto",
|
marginRight: "auto",
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
color: userdata?.support
|
color: currentOpenTab === "security"
|
||||||
? currentOpenTab === "security" && currentPath.includes("/security")
|
|
||||||
? "#F1F1F1"
|
? "#F1F1F1"
|
||||||
: "#C8C8C8"
|
: "#C8C8C8"
|
||||||
: "#6F6F6F",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Content
|
Discover
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -1452,6 +1466,8 @@ useEffect(() => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{recentworkflows?.length > 0 ?
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -1496,6 +1512,8 @@ useEffect(() => {
|
|||||||
}) }
|
}) }
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
: null }
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -1484,6 +1484,14 @@ const ParsedAction = (props) => {
|
|||||||
|
|
||||||
|
|
||||||
const selectedAppIcon = selectedAction.large_image
|
const selectedAppIcon = selectedAction.large_image
|
||||||
|
|
||||||
|
var newAppname = selectedAction?.name?.charAt(0).toUpperCase() + selectedAction?.name?.substring(1)
|
||||||
|
if (newAppname === undefined || newAppname === null) {
|
||||||
|
newAppname = ""
|
||||||
|
} else {
|
||||||
|
newAppname = newAppname.replaceAll("_", " ")
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={appApiViewStyle} id="parsed_action_view">
|
<div style={appApiViewStyle} id="parsed_action_view">
|
||||||
|
|
||||||
@@ -1506,11 +1514,9 @@ const ParsedAction = (props) => {
|
|||||||
border: "2px solid rgba(255,255,255,0.3)",
|
border: "2px solid rgba(255,255,255,0.3)",
|
||||||
}} />
|
}} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<h3 style={{ }}>
|
<h3 style={{ }}>
|
||||||
{(
|
{newAppname}
|
||||||
selectedAction?.app_name?.charAt(0).toUpperCase() +
|
|
||||||
selectedAction?.app_name?.substring(1)
|
|
||||||
)?.replaceAll("_", " ")}
|
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div style={{display: "flex", marginTop: 0, }}>
|
<div style={{display: "flex", marginTop: 0, }}>
|
||||||
|
|||||||
@@ -409,8 +409,8 @@ const NotificationItem = memo((props) => {
|
|||||||
{data.read === false ?
|
{data.read === false ?
|
||||||
<Chip
|
<Chip
|
||||||
label={"Unread"}
|
label={"Unread"}
|
||||||
variant="outlined"
|
variant="contained"
|
||||||
color="primary"
|
color="secondary"
|
||||||
style={{marginRight: 15, height: 25, }}
|
style={{marginRight: 15, height: 25, }}
|
||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
@@ -435,15 +435,12 @@ const NotificationItem = memo((props) => {
|
|||||||
{data.description}
|
{data.description}
|
||||||
</Typography >
|
</Typography >
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
|
<ButtonGroup style={{marginTop: 15, minHeight: 50, maxHeight: 50, }}>
|
||||||
<Button
|
<Button
|
||||||
style={{
|
style={{
|
||||||
marginTop: 15,
|
|
||||||
textTransform: "none",
|
textTransform: "none",
|
||||||
fontSize: 16,
|
|
||||||
marginRight: 5,
|
|
||||||
border: "1px solid #ff8544",
|
border: "1px solid #ff8544",
|
||||||
color: "#ff8544",
|
color: "#ff8544",
|
||||||
width: 130,
|
|
||||||
opacity: data.reference_url ? 1 : 0.5,
|
opacity: data.reference_url ? 1 : 0.5,
|
||||||
cursor: data.reference_url ? "pointer" : "not-allowed",
|
cursor: data.reference_url ? "pointer" : "not-allowed",
|
||||||
}}
|
}}
|
||||||
@@ -459,21 +456,16 @@ const NotificationItem = memo((props) => {
|
|||||||
|
|
||||||
{data.read === false ? (
|
{data.read === false ? (
|
||||||
<Button
|
<Button
|
||||||
sx={{
|
variant="outlined"
|
||||||
marginTop: "15px",
|
color="secondary"
|
||||||
border: "none",
|
style={{
|
||||||
textTransform: "none",
|
height: 50,
|
||||||
fontSize: 16,
|
|
||||||
color: "#ffffff",
|
|
||||||
marginRight: "5px",
|
|
||||||
backgroundColor: "transparent",
|
|
||||||
"&:hover": { backgroundColor: "transparent" },
|
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dismissNotification(data.id);
|
dismissNotification(data.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Dismiss
|
Mark Read
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@@ -482,16 +474,10 @@ const NotificationItem = memo((props) => {
|
|||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="secondary"
|
||||||
style={{
|
style={{
|
||||||
marginTop: 15,
|
|
||||||
textTransform: "none",
|
textTransform: "none",
|
||||||
fontSize: 16,
|
|
||||||
width: 130,
|
|
||||||
border: data.ignored
|
|
||||||
? "1px solid #2bc07e"
|
|
||||||
: "1px solid #ff8544",
|
|
||||||
color: data.ignored ? "#ffffff" : "#ff8544",
|
|
||||||
backgroundColor: data.ignored ? "#2bc07e" : "transparent",
|
|
||||||
opacity: data.ignored || data.dismissable ? 1 : 0.5,
|
opacity: data.ignored || data.dismissable ? 1 : 0.5,
|
||||||
cursor: data.dismissable ? "pointer" : "not-allowed",
|
cursor: data.dismissable ? "pointer" : "not-allowed",
|
||||||
}}
|
}}
|
||||||
@@ -507,6 +493,7 @@ const NotificationItem = memo((props) => {
|
|||||||
{data.ignored ? "Re-enable" : "Disable"}
|
{data.ignored ? "Re-enable" : "Disable"}
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</ButtonGroup>
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
|||||||
@@ -66,27 +66,27 @@ import "ace-builds/src-noconflict/ext-language_tools";
|
|||||||
import "ace-builds/src-noconflict/ext-searchbox";
|
import "ace-builds/src-noconflict/ext-searchbox";
|
||||||
|
|
||||||
const liquidFilters = [
|
const liquidFilters = [
|
||||||
{"name": "Default", "value": `default: []`, "example": `{{ "" | default: "no input" }}`},
|
{ "name": "Default", "value": `default: []`, "example": `{{ "" | default: "no input" }}` },
|
||||||
{"name": "Split", "value": `split: ","`, "example": `{{ "this,can,become,a,list" | split: "," }}`},
|
{ "name": "Split", "value": `split: ","`, "example": `{{ "this,can,become,a,list" | split: "," }}` },
|
||||||
{"name": "Join", "value": `join: ","`, "example": `{{ ["this","can","become","a","string"] | join: "," }}`},
|
{ "name": "Join", "value": `join: ","`, "example": `{{ ["this","can","become","a","string"] | join: "," }}` },
|
||||||
{"name": "Size", "value": "size", "example": ""},
|
{ "name": "Size", "value": "size", "example": "" },
|
||||||
{"name": "Date", "value": `date: "%Y%m%d"`, "example": `{{ "now" | date: "%s" }}`},
|
{ "name": "Date", "value": `date: "%Y%m%d"`, "example": `{{ "now" | date: "%s" }}` },
|
||||||
{"name": "Escape String", "value": `{{ \"\"\"'string with weird'" quotes\"\"\" | escape_string }}`, "example": ``},
|
{ "name": "Escape String", "value": `{{ \"\"\"'string with weird'" quotes\"\"\" | escape_string }}`, "example": `` },
|
||||||
{"name": "Flatten", "value": `flatten`, "example": `{{ [1, [1, 2], [2, 3, 4]] | flatten }}`},
|
{ "name": "Flatten", "value": `flatten`, "example": `{{ [1, [1, 2], [2, 3, 4]] | flatten }}` },
|
||||||
{"name": "URL encode", "value": `url_encode`, "example": `{{ "https://www.google.com/search?q=hello world" | url_encode }}`},
|
{ "name": "URL encode", "value": `url_encode`, "example": `{{ "https://www.google.com/search?q=hello world" | url_encode }}` },
|
||||||
{"name": "URL decode ", "value": `url_decode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | url_decode }}`},
|
{ "name": "URL decode ", "value": `url_decode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | url_decode }}` },
|
||||||
{"name": "base64_encode", "value": `base64_encode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | base64_encode }}`},
|
{ "name": "base64_encode", "value": `base64_encode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | base64_encode }}` },
|
||||||
{"name": "base64_decode", "value": `base64_decode`, "example": `{{ "aGVsbG8K" | base64_encode }}`},
|
{ "name": "base64_decode", "value": `base64_decode`, "example": `{{ "aGVsbG8K" | base64_encode }}` },
|
||||||
]
|
]
|
||||||
|
|
||||||
const mathFilters = [
|
const mathFilters = [
|
||||||
{"name": "Plus", "value": "plus: 1", "example": `{{ "1" | plus: 1 }}`},
|
{ "name": "Plus", "value": "plus: 1", "example": `{{ "1" | plus: 1 }}` },
|
||||||
{"name": "Minus", "value": "minus: 1", "example": `{{ "1" | minus: 1 }}`},
|
{ "name": "Minus", "value": "minus: 1", "example": `{{ "1" | minus: 1 }}` },
|
||||||
]
|
]
|
||||||
|
|
||||||
const pythonFilters = [
|
const pythonFilters = [
|
||||||
{"name": "Hello World", "value": `{% python %}\nprint("hello world")\n{% endpython %}`, "example": ``},
|
{ "name": "Hello World", "value": `{% python %}\nprint("hello world")\n{% endpython %}`, "example": `` },
|
||||||
{"name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": ``},
|
{ "name": "Handle JSON", "value": `{% python %}\nimport json\njsondata = json.loads(r"""$nodename""")\n{% endpython %}`, "example": `` },
|
||||||
]
|
]
|
||||||
|
|
||||||
const extensions = []
|
const extensions = []
|
||||||
@@ -104,7 +104,7 @@ const CodeEditor = (props) => {
|
|||||||
runUpdateText,
|
runUpdateText,
|
||||||
toolsAppId,
|
toolsAppId,
|
||||||
parameterName,
|
parameterName,
|
||||||
selectedAction ,
|
selectedAction,
|
||||||
workflowExecutions,
|
workflowExecutions,
|
||||||
getParents,
|
getParents,
|
||||||
activeDialog,
|
activeDialog,
|
||||||
@@ -184,9 +184,9 @@ const CodeEditor = (props) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i=0; i < actionlist.length; i++){
|
for (var i = 0; i < actionlist.length; i++) {
|
||||||
allVariables.push('$'+actionlist[i].autocomplete.toLowerCase())
|
allVariables.push('$' + actionlist[i].autocomplete.toLowerCase())
|
||||||
tmpVariables.push('$'+actionlist[i].autocomplete.toLowerCase())
|
tmpVariables.push('$' + actionlist[i].autocomplete.toLowerCase())
|
||||||
|
|
||||||
var parsedPaths = []
|
var parsedPaths = []
|
||||||
if (typeof actionlist[i].example === "object") {
|
if (typeof actionlist[i].example === "object") {
|
||||||
@@ -194,7 +194,7 @@ const CodeEditor = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var key in parsedPaths) {
|
for (var key in parsedPaths) {
|
||||||
const fullpath = "$"+actionlist[i].autocomplete.toLowerCase()+parsedPaths[key].autocomplete
|
const fullpath = "$" + actionlist[i].autocomplete.toLowerCase() + parsedPaths[key].autocomplete
|
||||||
if (!allVariables.includes(fullpath)) {
|
if (!allVariables.includes(fullpath)) {
|
||||||
allVariables.push(fullpath)
|
allVariables.push(fullpath)
|
||||||
allVariables.push(fullpath.toLowerCase())
|
allVariables.push(fullpath.toLowerCase())
|
||||||
@@ -295,7 +295,7 @@ const CodeEditor = (props) => {
|
|||||||
console.log("Parents: ", parents)
|
console.log("Parents: ", parents)
|
||||||
var actionlist = []
|
var actionlist = []
|
||||||
if (parents.length > 1) {
|
if (parents.length > 1) {
|
||||||
for (let [key,keyval] in Object.entries(parents)) {
|
for (let [key, keyval] in Object.entries(parents)) {
|
||||||
const item = parents[key];
|
const item = parents[key];
|
||||||
if (item.label === "Execution Argument") {
|
if (item.label === "Execution Argument") {
|
||||||
continue;
|
continue;
|
||||||
@@ -307,7 +307,7 @@ const CodeEditor = (props) => {
|
|||||||
if (workflowExecutions.length > 0) {
|
if (workflowExecutions.length > 0) {
|
||||||
// Look for the ID
|
// Look for the ID
|
||||||
const found = false;
|
const found = false;
|
||||||
for (let [key,keyval] in Object.entries(workflowExecutions)) {
|
for (let [key, keyval] in Object.entries(workflowExecutions)) {
|
||||||
if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
|
if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -499,21 +499,21 @@ const CodeEditor = (props) => {
|
|||||||
var variable_ranges = []
|
var variable_ranges = []
|
||||||
var popup = false
|
var popup = false
|
||||||
|
|
||||||
for(var ch=0; ch < code_line.length; ch++){
|
for (var ch = 0; ch < code_line.length; ch++) {
|
||||||
if(code_line[ch] === '$'){
|
if (code_line[ch] === '$') {
|
||||||
dollar_occurences.push(ch)
|
dollar_occurences.push(ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var variable_occurences = code_line.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
var variable_occurences = code_line.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||||
|
|
||||||
try{
|
try {
|
||||||
for(var occ = 0; occ < variable_occurences.length; occ++){
|
for (var occ = 0; occ < variable_occurences.length; occ++) {
|
||||||
dollar_occurences_len.push(variable_occurences[occ].length)
|
dollar_occurences_len.push(variable_occurences[occ].length)
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) { }
|
||||||
|
|
||||||
for(var occ = 0; occ < dollar_occurences.length; occ++){
|
for (var occ = 0; occ < dollar_occurences.length; occ++) {
|
||||||
// var temp_arr = []
|
// var temp_arr = []
|
||||||
// for(var occ_len = 0; occ_len<dollar_occurences_len[occ]; occ_len++){
|
// for(var occ_len = 0; occ_len<dollar_occurences_len[occ]; occ_len++){
|
||||||
// temp_arr.push(dollar_occurences[occ]+occ_len)
|
// temp_arr.push(dollar_occurences[occ]+occ_len)
|
||||||
@@ -522,24 +522,24 @@ const CodeEditor = (props) => {
|
|||||||
// temp_arr.push(temp_arr[temp_arr.length-1]+1)
|
// temp_arr.push(temp_arr[temp_arr.length-1]+1)
|
||||||
// variable_ranges.push(temp_arr)
|
// variable_ranges.push(temp_arr)
|
||||||
var temp_arr = [dollar_occurences[occ]]
|
var temp_arr = [dollar_occurences[occ]]
|
||||||
for(var occ_len = 0; occ_len < dollar_occurences_len[occ]; occ_len++){
|
for (var occ_len = 0; occ_len < dollar_occurences_len[occ]; occ_len++) {
|
||||||
temp_arr.push(dollar_occurences[occ]+occ_len+1)
|
temp_arr.push(dollar_occurences[occ] + occ_len + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(temp_arr.length==1) {
|
if (temp_arr.length == 1) {
|
||||||
temp_arr.push(temp_arr[temp_arr.length-1]+1)
|
temp_arr.push(temp_arr[temp_arr.length - 1] + 1)
|
||||||
}
|
}
|
||||||
variable_ranges.push(temp_arr)
|
variable_ranges.push(temp_arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var occ = 0; occ<variable_ranges.length; occ++){
|
for (var occ = 0; occ < variable_ranges.length; occ++) {
|
||||||
for(var occ1 = 0; occ1<variable_ranges[occ].length; occ1++){
|
for (var occ1 = 0; occ1 < variable_ranges[occ].length; occ1++) {
|
||||||
// console.log(variable_ranges[occ][occ1])
|
// console.log(variable_ranges[occ][occ1])
|
||||||
if(loc === variable_ranges[occ][occ1]){
|
if (loc === variable_ranges[occ][occ1]) {
|
||||||
popup = true
|
popup = true
|
||||||
setCurrentLocation([line, dollar_occurences[occ]])
|
setCurrentLocation([line, dollar_occurences[occ]])
|
||||||
|
|
||||||
try{
|
try {
|
||||||
setCurrentVariable(variable_occurences[occ])
|
setCurrentVariable(variable_occurences[occ])
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -572,7 +572,7 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
// Makes sure #0 and # are same, as we only visualize first one anyway
|
// Makes sure #0 and # are same, as we only visualize first one anyway
|
||||||
if (tmpitem.startsWith("#")) {
|
if (tmpitem.startsWith("#")) {
|
||||||
removedIndexes += tmpitem.length-1
|
removedIndexes += tmpitem.length - 1
|
||||||
tmpitem = "#"
|
tmpitem = "#"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,8 +614,8 @@ const CodeEditor = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dollar_occurence_len = []
|
var dollar_occurence_len = []
|
||||||
try{
|
try {
|
||||||
for(let occ = 0; occ < variable_occurence.length; occ++){
|
for (let occ = 0; occ < variable_occurence.length; occ++) {
|
||||||
dollar_occurence_len.push(variable_occurence[occ].length)
|
dollar_occurence_len.push(variable_occurence[occ].length)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -630,7 +630,7 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
for (let occ = 0; occ < variable_occurence.length; occ++) {
|
for (let occ = 0; occ < variable_occurence.length; occ++) {
|
||||||
const fixedVariable = fixVariable(variable_occurence[occ])
|
const fixedVariable = fixVariable(variable_occurence[occ])
|
||||||
var correctVariable = availableVariables.includes(fixedVariable.toLowerCase())
|
var correctVariable = availableVariables.includes(fixedVariable)
|
||||||
|
|
||||||
var startCh = dollar_occurence[occ]
|
var startCh = dollar_occurence[occ]
|
||||||
var endCh = dollar_occurence[occ] + dollar_occurence_len[occ]
|
var endCh = dollar_occurence[occ] + dollar_occurence_len[occ]
|
||||||
@@ -679,10 +679,10 @@ const CodeEditor = (props) => {
|
|||||||
var parsedVariable = currentVariable
|
var parsedVariable = currentVariable
|
||||||
if (currentVariable === undefined || currentVariable === null) {
|
if (currentVariable === undefined || currentVariable === null) {
|
||||||
console.log("Location: ", currentLocation)
|
console.log("Location: ", currentLocation)
|
||||||
parsedVariable= "$"
|
parsedVariable = "$"
|
||||||
}
|
}
|
||||||
|
|
||||||
code_lines[currentLine] = code_lines[currentLine].slice(0,currentLocation[1]) + "$" + swapVariable + code_lines[currentLine].slice(currentLocation[1]+parsedVariable.length,)
|
code_lines[currentLine] = code_lines[currentLine].slice(0, currentLocation[1]) + "$" + swapVariable + code_lines[currentLine].slice(currentLocation[1] + parsedVariable.length,)
|
||||||
// console.log(code_lines)
|
// console.log(code_lines)
|
||||||
var updatedCode = code_lines.join('\n')
|
var updatedCode = code_lines.join('\n')
|
||||||
// console.log(updatedCode)
|
// console.log(updatedCode)
|
||||||
@@ -721,7 +721,7 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
var valuefound = false
|
var valuefound = false
|
||||||
for (var j = 0; j < actionlist.length; j++) {
|
for (var j = 0; j < actionlist.length; j++) {
|
||||||
if(fixedVariable.slice(1,).toLowerCase() !== actionlist[j].autocomplete.toLowerCase()) {
|
if (fixedVariable.slice(1,).toLowerCase() !== actionlist[j].autocomplete.toLowerCase()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,16 +746,16 @@ const CodeEditor = (props) => {
|
|||||||
if (!valuefound) {
|
if (!valuefound) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valuefound && availableVariables.includes(fixedVariable.toLowerCase())) {
|
if (!valuefound && availableVariables.includes(fixedVariable)) {
|
||||||
var shouldbreak = false
|
var shouldbreak = false
|
||||||
for (var k=0; k < actionlist.length; k++){
|
for (var k = 0; k < actionlist.length; k++) {
|
||||||
var parsedPaths = []
|
var parsedPaths = []
|
||||||
if (typeof actionlist[k].example === "object") {
|
if (typeof actionlist[k].example === "object") {
|
||||||
parsedPaths = GetParsedPaths(actionlist[k].example, "");
|
parsedPaths = GetParsedPaths(actionlist[k].example, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var key in parsedPaths) {
|
for (var key in parsedPaths) {
|
||||||
const fullpath = "$"+actionlist[k].autocomplete.toLowerCase()+parsedPaths[key].autocomplete.toLowerCase()
|
const fullpath = "$" + actionlist[k].autocomplete.toLowerCase() + parsedPaths[key].autocomplete.toLowerCase()
|
||||||
if (fullpath !== fixedVariable.toLowerCase()) {
|
if (fullpath !== fixedVariable.toLowerCase()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -877,9 +877,9 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
if (edited === false) {
|
if (edited === false) {
|
||||||
if (!item.value.includes("{%") && !item.value.includes("{{")) {
|
if (!item.value.includes("{%") && !item.value.includes("{{")) {
|
||||||
setlocalcodedata(localcodedata+" | "+item.value+" }}")
|
setlocalcodedata(localcodedata + " | " + item.value + " }}")
|
||||||
} else {
|
} else {
|
||||||
setlocalcodedata(localcodedata+item.value)
|
setlocalcodedata(localcodedata + item.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,9 +897,9 @@ const CodeEditor = (props) => {
|
|||||||
const appid = toolsAppId !== undefined && toolsAppId !== null && toolsAppId.length > 0 ? toolsAppId : "3e2bdf9d5069fe3f4746c29d68785a6a"
|
const appid = toolsAppId !== undefined && toolsAppId !== null && toolsAppId.length > 0 ? toolsAppId : "3e2bdf9d5069fe3f4746c29d68785a6a"
|
||||||
|
|
||||||
const actionname = selectedAction.name === "execute_python" && !inputdata.replaceAll(" ", "").includes("{%python%}") ? "execute_python" : selectedAction.name === "execute_bash" ? "execute_bash" : "repeat_back_to_me"
|
const actionname = selectedAction.name === "execute_python" && !inputdata.replaceAll(" ", "").includes("{%python%}") ? "execute_python" : selectedAction.name === "execute_bash" ? "execute_bash" : "repeat_back_to_me"
|
||||||
const params = actionname === "execute_python" ? [{"name": "code", "value":inputdata}] : actionname === "execute_bash" ? [{"name": "code", "value":inputdata}, {"name": "shuffle_input", "value": "", }] : [{"name":"call", "value": inputdata}]
|
const params = actionname === "execute_python" ? [{ "name": "code", "value": inputdata }] : actionname === "execute_bash" ? [{ "name": "code", "value": inputdata }, { "name": "shuffle_input", "value": "", }] : [{ "name": "call", "value": inputdata }]
|
||||||
|
|
||||||
const actiondata = {"description":"Repeats the call parameter","id":"","name":actionname,"label":"","node_type":"","environment":"","sharing":false,"private_id":"","public_id":"","app_id": appid,"tags":null,"authentication":[],"tested":false,"parameters": params, "execution_variable":{"description":"","id":"","name":"","value":""},"returns":{"description":"","example":"","id":"","schema":{"type":"string"}},"authentication_id":"","example":"","auth_not_required":false,"source_workflow":"","run_magic_output":false,"run_magic_input":false,"execution_delay":0,"app_name":"Shuffle Tools","app_version":"1.2.0","selectedAuthentication":{}}
|
const actiondata = { "description": "Repeats the call parameter", "id": "", "name": actionname, "label": "", "node_type": "", "environment": "", "sharing": false, "private_id": "", "public_id": "", "app_id": appid, "tags": null, "authentication": [], "tested": false, "parameters": params, "execution_variable": { "description": "", "id": "", "name": "", "value": "" }, "returns": { "description": "", "example": "", "id": "", "schema": { "type": "string" } }, "authentication_id": "", "example": "", "auth_not_required": false, "source_workflow": "", "run_magic_output": false, "run_magic_input": false, "execution_delay": 0, "app_name": "Shuffle Tools", "app_version": "1.2.0", "selectedAuthentication": {} }
|
||||||
|
|
||||||
setExecutionResult({
|
setExecutionResult({
|
||||||
"valid": false,
|
"valid": false,
|
||||||
@@ -929,18 +929,18 @@ const CodeEditor = (props) => {
|
|||||||
//console.log("RESPONSE: ", responseJson)
|
//console.log("RESPONSE: ", responseJson)
|
||||||
var newResult = {}
|
var newResult = {}
|
||||||
if (responseJson.success === true && responseJson.result !== null && responseJson.result !== undefined && responseJson.result.length > 0) {
|
if (responseJson.success === true && responseJson.result !== null && responseJson.result !== undefined && responseJson.result.length > 0) {
|
||||||
const result = responseJson.result.slice(0, 50)+"..."
|
const result = responseJson.result.slice(0, 50) + "..."
|
||||||
//toast("SUCCESS: "+result)
|
//toast("SUCCESS: "+result)
|
||||||
|
|
||||||
const validate = validateJson(responseJson.result)
|
const validate = validateJson(responseJson.result)
|
||||||
newResult = validate
|
newResult = validate
|
||||||
} else if (responseJson.success === false && responseJson.reason !== undefined && responseJson.reason !== null) {
|
} else if (responseJson.success === false && responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||||
toast(responseJson.reason)
|
toast(responseJson.reason)
|
||||||
newResult = {"valid": false, "result": responseJson.reason}
|
newResult = { "valid": false, "result": responseJson.reason }
|
||||||
} else if (responseJson.success === true) {
|
} else if (responseJson.success === true) {
|
||||||
newResult = {"valid": false, "result": "Couldn't finish execution. Please fill all the required fields, and retry the execution."}
|
newResult = { "valid": false, "result": "Couldn't finish execution. Please fill all the required fields, and retry the execution." }
|
||||||
} else {
|
} else {
|
||||||
newResult = {"valid": false, "result": "Couldn't finish execution (2). Please fill all the required fields, and validate the execution."}
|
newResult = { "valid": false, "result": "Couldn't finish execution (2). Please fill all the required fields, and validate the execution." }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseJson.errors !== undefined && responseJson.errors !== null && responseJson.errors.length > 0) {
|
if (responseJson.errors !== undefined && responseJson.errors !== null && responseJson.errors.length > 0) {
|
||||||
@@ -1054,14 +1054,14 @@ const CodeEditor = (props) => {
|
|||||||
aria-labelledby="draggable-dialog-title"
|
aria-labelledby="draggable-dialog-title"
|
||||||
// disableBackdropClick={true}
|
// disableBackdropClick={true}
|
||||||
disableEnforceFocus={true}
|
disableEnforceFocus={true}
|
||||||
style={{ pointerEvents: "none", zIndex: activeDialog === "codeeditor" ? 1200 : 1100}}
|
style={{ pointerEvents: "none", zIndex: activeDialog === "codeeditor" ? 1200 : 1100 }}
|
||||||
hideBackdrop={true}
|
hideBackdrop={true}
|
||||||
open={expansionModalOpen}
|
open={expansionModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
console.log("In closer")
|
console.log("In closer")
|
||||||
|
|
||||||
if (changeActionParameterCodeMirror !== undefined) {
|
if (changeActionParameterCodeMirror !== undefined) {
|
||||||
changeActionParameterCodeMirror({target: {value: ""}}, fieldCount, localcodedata)
|
changeActionParameterCodeMirror({ target: { value: "" } }, fieldCount, localcodedata)
|
||||||
} else {
|
} else {
|
||||||
console.log("No action called changeActionParameterCodeMirror in code editor")
|
console.log("No action called changeActionParameterCodeMirror in code editor")
|
||||||
}
|
}
|
||||||
@@ -1084,7 +1084,7 @@ const CodeEditor = (props) => {
|
|||||||
maxHeight: isMobile ? "100%" : 700,
|
maxHeight: isMobile ? "100%" : 700,
|
||||||
border: theme.palette.defaultBorder,
|
border: theme.palette.defaultBorder,
|
||||||
padding: isMobile ? "25px 10px 25px 10px" : 25,
|
padding: isMobile ? "25px 10px 25px 10px" : 25,
|
||||||
zoom: 0.8,
|
// zoom: 0.8,
|
||||||
backgroundColor: "black",
|
backgroundColor: "black",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@@ -1096,7 +1096,7 @@ const CodeEditor = (props) => {
|
|||||||
title={`The File content is loading. Please wait a moment.`}
|
title={`The File content is loading. Please wait a moment.`}
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<CircularProgress style={{position: "absolute", right: 106, top: 6, }}/>
|
<CircularProgress style={{ position: "absolute", right: 106, top: 6, }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
@@ -1142,18 +1142,18 @@ const CodeEditor = (props) => {
|
|||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div style={{display: "flex"}}>
|
<div style={{ display: "flex" }}>
|
||||||
<div style={{flex: 1, }}>
|
<div style={{ flex: 1, }}>
|
||||||
{ isFileEditor ?
|
{isFileEditor ?
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{display: "flex"}}>
|
<div style={{ display: "flex" }}>
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
style={{
|
style={{
|
||||||
paddingBottom:20,
|
paddingBottom: 20,
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1167,7 +1167,7 @@ const CodeEditor = (props) => {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{display: "flex"}}>
|
<div style={{ display: "flex" }}>
|
||||||
{/*
|
{/*
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
id="draggable-dialog-title"
|
id="draggable-dialog-title"
|
||||||
@@ -1180,19 +1180,19 @@ const CodeEditor = (props) => {
|
|||||||
Code Editor
|
Code Editor
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
*/}
|
*/}
|
||||||
{ isFileEditor ? null :
|
{isFileEditor ? null :
|
||||||
<div style={{display: "flex", maxHeight: 40, }}>
|
<div style={{ display: "flex", maxHeight: 40, }}>
|
||||||
{selectedAction?.name === "execute_python" ?
|
{selectedAction?.name === "execute_python" ?
|
||||||
<Typography variant="body1" style={{marginTop: 5, }}>
|
<Typography variant="body1" style={{ marginTop: 5, }}>
|
||||||
Run Python Code
|
Run Python Code
|
||||||
</Typography>
|
</Typography>
|
||||||
:
|
:
|
||||||
selectedAction.name === "execute_bash" ?
|
selectedAction.name === "execute_bash" ?
|
||||||
<Typography variant="body1" style={{marginTop: 5, }}>
|
<Typography variant="body1" style={{ marginTop: 5, }}>
|
||||||
Run Bash Code
|
Run Bash Code
|
||||||
</Typography>
|
</Typography>
|
||||||
:
|
:
|
||||||
<div style={{display: "flex", }}>
|
<div style={{ display: "flex", }}>
|
||||||
<Button
|
<Button
|
||||||
id="basic-button"
|
id="basic-button"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -1442,7 +1442,7 @@ const CodeEditor = (props) => {
|
|||||||
handleItemClick([innerdata]);
|
handleItemClick([innerdata]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Paper style={{minHeight: 550, maxHeight: 550, minWidth: 275, maxWidth: 275, position: "fixed", left: menuPosition1.left-270, padding: "10px 0px 10px 10px", overflow: "hidden", overflowY: "auto", border: "1px solid rgba(255,255,255,0.3)",}}>
|
<Paper style={{ minHeight: 550, maxHeight: 550, minWidth: 275, maxWidth: 275, position: "fixed", left: menuPosition1.left - 270, padding: "10px 0px 10px 10px", overflow: "hidden", overflowY: "auto", border: "1px solid rgba(255,255,255,0.3)", }}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={innerdata.name}
|
key={innerdata.name}
|
||||||
style={{
|
style={{
|
||||||
@@ -1461,7 +1461,7 @@ const CodeEditor = (props) => {
|
|||||||
handleItemClick([innerdata]);
|
handleItemClick([innerdata]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" style={{paddingBottom: 5}}>
|
<Typography variant="h6" style={{ paddingBottom: 5 }}>
|
||||||
{innerdata.name}
|
{innerdata.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -1470,19 +1470,19 @@ const CodeEditor = (props) => {
|
|||||||
//<VpnKeyIcon style={iconStyle} />
|
//<VpnKeyIcon style={iconStyle} />
|
||||||
const icon =
|
const icon =
|
||||||
pathdata.type === "value" ? (
|
pathdata.type === "value" ? (
|
||||||
<span style={{marginLeft: 9, }} />
|
<span style={{ marginLeft: 9, }} />
|
||||||
) : pathdata.type === "list" ? (
|
) : pathdata.type === "list" ? (
|
||||||
<FormatListNumberedIcon style={{marginLeft: 9, marginRight: 10, }} />
|
<FormatListNumberedIcon style={{ marginLeft: 9, marginRight: 10, }} />
|
||||||
) : (
|
) : (
|
||||||
<CircleIcon style={{marginLeft: 9, marginRight: 10, color: coverColor}}/>
|
<CircleIcon style={{ marginLeft: 9, marginRight: 10, color: coverColor }} />
|
||||||
);
|
);
|
||||||
//<ExpandMoreIcon style={iconStyle} />
|
//<ExpandMoreIcon style={iconStyle} />
|
||||||
|
|
||||||
const indentation_count = (pathdata.name.match(/\./g) || []).length+1
|
const indentation_count = (pathdata.name.match(/\./g) || []).length + 1
|
||||||
//const boxPadding = pathdata.type === "object" ? "10px 0px 0px 0px" : 0
|
//const boxPadding = pathdata.type === "object" ? "10px 0px 0px 0px" : 0
|
||||||
const boxPadding = 0
|
const boxPadding = 0
|
||||||
const namesplit = pathdata.name.split(".")
|
const namesplit = pathdata.name.split(".")
|
||||||
const newname = namesplit[namesplit.length-1]
|
const newname = namesplit[namesplit.length - 1]
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={pathdata.name}
|
key={pathdata.name}
|
||||||
@@ -1508,11 +1508,11 @@ const CodeEditor = (props) => {
|
|||||||
<div style={{ display: "flex", height: 30, }}>
|
<div style={{ display: "flex", height: 30, }}>
|
||||||
{Array(indentation_count).fill().map((subdata, subindex) => {
|
{Array(indentation_count).fill().map((subdata, subindex) => {
|
||||||
return (
|
return (
|
||||||
<div key={subindex} style={{marginLeft: 20, height: 30, width: 1, backgroundColor: coverColor,}} />
|
<div key={subindex} style={{ marginLeft: 20, height: 30, width: 1, backgroundColor: coverColor, }} />
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{icon} {newname}
|
{icon} {newname}
|
||||||
{pathdata.type === "list" ? <SquareFootIcon style={{marginleft: 10, }} onClick={(e) => {
|
{pathdata.type === "list" ? <SquareFootIcon style={{ marginleft: 10, }} onClick={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
@@ -1521,7 +1521,7 @@ const CodeEditor = (props) => {
|
|||||||
// Removing .list from autocomplete
|
// Removing .list from autocomplete
|
||||||
var newname = pathdata.name
|
var newname = pathdata.name
|
||||||
if (newname.length > 5) {
|
if (newname.length > 5) {
|
||||||
newname = newname.slice(0, newname.length-5)
|
newname = newname.slice(0, newname.length - 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
//selectedActionParameters[count].value += `{{ $${innerdata.name}.${newname} | size }}`
|
//selectedActionParameters[count].value += `{{ $${innerdata.name}.${newname} | size }}`
|
||||||
@@ -1617,9 +1617,9 @@ const CodeEditor = (props) => {
|
|||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
{isAiLoading ?
|
{isAiLoading ?
|
||||||
<CircularProgress style={{height: 20, width: 20, color: "rgba(255,255,255,0.7)"}}/>
|
<CircularProgress style={{ height: 20, width: 20, color: "rgba(255,255,255,0.7)" }} />
|
||||||
:
|
:
|
||||||
<AutoFixHighIcon style={{color: "rgba(255,255,255,0.7)"}}/>
|
<AutoFixHighIcon style={{ color: "rgba(255,255,255,0.7)" }} />
|
||||||
}
|
}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -1690,7 +1690,7 @@ const CodeEditor = (props) => {
|
|||||||
}}
|
}}
|
||||||
// options={options}
|
// options={options}
|
||||||
/>
|
/>
|
||||||
): null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -1701,7 +1701,7 @@ const CodeEditor = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isFileEditor ? null :
|
{isFileEditor ? null :
|
||||||
<div style={{flex: 1, marginLeft: 5, borderLeft: "1px solid rgba(255,255,255,0.3)", paddingLeft: 5, overflow: "hidden", }}>
|
<div style={{ flex: 1, marginLeft: 5, borderLeft: "1px solid rgba(255,255,255,0.3)", paddingLeft: 5, overflow: "hidden", }}>
|
||||||
<div>
|
<div>
|
||||||
{isMobile ? null :
|
{isMobile ? null :
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
@@ -1713,7 +1713,7 @@ const CodeEditor = (props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span style={{color: "white"}}>
|
<span style={{ color: "white" }}>
|
||||||
|
|
||||||
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" || selectedAction.name === "execute_bash" ? "Code to run" : `Expected Output for '${selectedAction.name}'`}
|
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" || selectedAction.name === "execute_bash" ? "Code to run" : `Expected Output for '${selectedAction.name}'`}
|
||||||
</span>
|
</span>
|
||||||
@@ -1722,7 +1722,7 @@ const CodeEditor = (props) => {
|
|||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style={{ }}>
|
<div style={{}}>
|
||||||
<Tooltip title="Try it! This runs the Shuffle Tools 'repeat back to me' or 'execute python' action with what you see in the expected output window. Commonly used to test your Python scripts or Liquid filters, not requiring the full workflow to run again." placement="top">
|
<Tooltip title="Try it! This runs the Shuffle Tools 'repeat back to me' or 'execute python' action with what you see in the expected output window. Commonly used to test your Python scripts or Liquid filters, not requiring the full workflow to run again." placement="top">
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@@ -1741,9 +1741,9 @@ const CodeEditor = (props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{executing ?
|
{executing ?
|
||||||
<CircularProgress style={{height: 18, width: 18, }} />
|
<CircularProgress style={{ height: 18, width: 18, }} />
|
||||||
:
|
:
|
||||||
<span>{selectedAction === undefined ? "" : selectedAction.name === "execute_python" ? "Run Python Code" : selectedAction.name === "execute_bash" ? "Run Bash" : "Try it"}<PlayArrowIcon style={{height: 18, width: 18, marginBottom: -4, marginLeft: 5, }} /> </span>
|
<span>{selectedAction === undefined ? "" : selectedAction.name === "execute_python" ? "Run Python Code" : selectedAction.name === "execute_bash" ? "Run Bash" : "Try it"}<PlayArrowIcon style={{ height: 18, width: 18, marginBottom: -4, marginLeft: 5, }} /> </span>
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -1826,13 +1826,13 @@ const CodeEditor = (props) => {
|
|||||||
name={"Test result"}
|
name={"Test result"}
|
||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
<span style={{maxHeight: 190, minHeight: 190, }}>
|
<span style={{ maxHeight: 190, minHeight: 190, }}>
|
||||||
{executionResult.result.length > 0 ?
|
{executionResult.result.length > 0 ?
|
||||||
<span style={{maxHeight: 150, overflow: "auto", marginTop: 20, }}>
|
<span style={{ maxHeight: 150, overflow: "auto", marginTop: 20, }}>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
<b>Test output</b>
|
<b>Test output</b>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" style={{whiteSpace: 'pre-line', }}>
|
<Typography variant="body2" style={{ whiteSpace: 'pre-line', }}>
|
||||||
{executionResult.result}
|
{executionResult.result}
|
||||||
</Typography>
|
</Typography>
|
||||||
</span>
|
</span>
|
||||||
@@ -1840,19 +1840,22 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Typography
|
<Typography
|
||||||
variant = 'body2'
|
variant='body2'
|
||||||
color = 'textSecondary'
|
color='textSecondary'
|
||||||
>
|
>
|
||||||
Output is based on the last VALID run of the node(s) you are referencing. Only updates when you refresh the Workflow Window.
|
Output is based on the last VALID run of the node(s) you are referencing. Refresh the page to get updated Variable values.
|
||||||
|
{selectedAction?.name === "execute_python" ?
|
||||||
|
"For Python: exit() to stop a python script ANYWHERE."
|
||||||
|
: null}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" style={{maxHeight: 150, overflow: "auto", marginTop: 20,}}>
|
<Typography variant="body2" style={{ maxHeight: 150, overflow: "auto", marginTop: 20, }}>
|
||||||
No test output yet.
|
No test output yet.
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{executionResult.errors !== undefined && executionResult.errors !== null && executionResult.errors.length > 0 ?
|
{executionResult.errors !== undefined && executionResult.errors !== null && executionResult.errors.length > 0 ?
|
||||||
<Typography variant="body2" style={{maxHeight: 100, overflow: "auto", color: "#f85a3e",}}>
|
<Typography variant="body2" style={{ maxHeight: 100, overflow: "auto", color: "#f85a3e", }}>
|
||||||
Errors ({executionResult.errors.length}): {executionResult.errors.join("\n")}
|
Errors ({executionResult.errors.length}): {executionResult.errors.join("\n")}
|
||||||
</Typography>
|
</Typography>
|
||||||
: null}
|
: null}
|
||||||
@@ -1865,7 +1868,7 @@ const CodeEditor = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style={{display: 'flex'}}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button
|
<Button
|
||||||
style={{
|
style={{
|
||||||
height: 35,
|
height: 35,
|
||||||
@@ -1902,7 +1905,7 @@ const CodeEditor = (props) => {
|
|||||||
|
|
||||||
// console.log(codedata)
|
// console.log(codedata)
|
||||||
// console.log(fieldCount)
|
// console.log(fieldCount)
|
||||||
if (isFileEditor === true){
|
if (isFileEditor === true) {
|
||||||
runUpdateText(fixedcodedata);
|
runUpdateText(fixedcodedata);
|
||||||
setcodedata(fixedcodedata);
|
setcodedata(fixedcodedata);
|
||||||
setExpansionModalOpen(false)
|
setExpansionModalOpen(false)
|
||||||
|
|||||||
@@ -3,11 +3,18 @@ export const Context = createContext();
|
|||||||
|
|
||||||
export const AppContext =(props) => {
|
export const AppContext =(props) => {
|
||||||
|
|
||||||
|
const currentLocation = window?.location?.pathname;
|
||||||
|
|
||||||
// Left side bar global states
|
// Left side bar global states
|
||||||
const [searchBarModalOpen, setSearchBarModalOpen] = useState(false);
|
const [searchBarModalOpen, setSearchBarModalOpen] = useState(false);
|
||||||
const [leftSideBarOpenByClick, setLeftSideBarOpenByClick] = useState(false);
|
const [leftSideBarOpenByClick, setLeftSideBarOpenByClick] = useState(currentLocation?.includes('/workflows/') ? false : true)
|
||||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentLocation?.includes('/workflows/') && leftSideBarOpenByClick === true) {
|
||||||
|
setLeftSideBarOpenByClick(false)
|
||||||
|
}
|
||||||
|
}, [leftSideBarOpenByClick])
|
||||||
|
|
||||||
//Calculate window width
|
//Calculate window width
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -12,18 +12,18 @@ const Admin2 = (props) => {
|
|||||||
const [orgRequest, setOrgRequest] = React.useState(true);
|
const [orgRequest, setOrgRequest] = React.useState(true);
|
||||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
||||||
const handleGetOrg = (orgId) => {
|
const handleGetOrg = (orgId) => {
|
||||||
if (
|
// if (
|
||||||
serverside !== true &&
|
// serverside !== true &&
|
||||||
window.location.search !== undefined &&
|
// window.location.search !== undefined &&
|
||||||
window.location.search !== null
|
// window.location.search !== null
|
||||||
) {
|
// ) {
|
||||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
// const urlSearchParams = new URLSearchParams(window.location.search);
|
||||||
const params = Object.fromEntries(urlSearchParams.entries());
|
// const params = Object.fromEntries(urlSearchParams.entries());
|
||||||
const foundorgid = params["org_id"];
|
// const foundorgid = params["org_id"];
|
||||||
if (foundorgid !== undefined && foundorgid !== null) {
|
// if (foundorgid !== undefined && foundorgid !== null) {
|
||||||
orgId = foundorgid;
|
// orgId = foundorgid;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
console.log("getting organization details for: ", orgId);
|
console.log("getting organization details for: ", orgId);
|
||||||
|
|
||||||
// if (orgId === undefined) {
|
// if (orgId === undefined) {
|
||||||
@@ -154,16 +154,15 @@ const Admin2 = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||||
const params = Object.fromEntries(urlSearchParams.entries());
|
const params = Object.fromEntries(urlSearchParams.entries());
|
||||||
const foundOrgID = params["org_id"]
|
const foundOrgID = params["org_id"]
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
if(foundOrgID !== null && foundOrgID !== undefined && userdata?.support && foundOrgID?.length > 0) {
|
if(foundOrgID !== null && foundOrgID !== undefined && userdata?.support && foundOrgID?.length > 0) {
|
||||||
handleClickChangeOrg(foundOrgID)
|
handleClickChangeOrg(foundOrgID)
|
||||||
}
|
}
|
||||||
}, [foundOrgID]);
|
}, [userdata]);
|
||||||
|
|
||||||
const handleClickChangeOrg = (orgId) => {
|
const handleClickChangeOrg = (orgId) => {
|
||||||
// Don't really care about the logout
|
// Don't really care about the logout
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
props.match = {}
|
props.match = {}
|
||||||
props.match.params = params
|
props.match.params = params
|
||||||
|
|
||||||
const { leftSideBarOpenByClick, windowWidth } = useContext(Context)
|
const { setLeftSideBarOpenByClick, leftSideBarOpenByClick, windowWidth } = useContext(Context)
|
||||||
const [workflowAsCode, setWorkflowAsCode] = useState(false);
|
const [workflowAsCode, setWorkflowAsCode] = useState(false);
|
||||||
|
|
||||||
var to_be_copied = "";
|
var to_be_copied = "";
|
||||||
@@ -8662,6 +8662,9 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
getApps()
|
getApps()
|
||||||
fetchUsecases()
|
fetchUsecases()
|
||||||
|
|
||||||
|
setLeftSideBarOpenByClick(false)
|
||||||
|
localStorage.setItem("expandLeftNav", false)
|
||||||
|
|
||||||
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
|
||||||
|
|
||||||
// FIXME: Don't check specific one here
|
// FIXME: Don't check specific one here
|
||||||
@@ -10018,6 +10021,13 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
const small = props.small
|
const small = props.small
|
||||||
const actionString = props.action
|
const actionString = props.action
|
||||||
const [hover, setHover] = React.useState(false);
|
const [hover, setHover] = React.useState(false);
|
||||||
|
React.useEffect(() => {
|
||||||
|
if(app.name === "Shuffle Tools"){
|
||||||
|
if (app.actions !== undefined && (app.actions === null || app.actions.length === 1)) {
|
||||||
|
loadAppConfig(app.id, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
if (app === undefined || app === null) {
|
if (app === undefined || app === null) {
|
||||||
return (
|
return (
|
||||||
@@ -10116,6 +10126,8 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
}}
|
}}
|
||||||
key={app.id}
|
key={app.id}
|
||||||
dragging={false}
|
dragging={false}
|
||||||
|
position={{x: 0, y: 0}}
|
||||||
|
defaultPosition={{x: 0, y: 0}}
|
||||||
>
|
>
|
||||||
<Paper
|
<Paper
|
||||||
square
|
square
|
||||||
@@ -10530,6 +10542,7 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
}}
|
}}
|
||||||
|
defaultPosition={{x: 0, y: 0}}
|
||||||
>
|
>
|
||||||
<div style={{ textDecoration: "none", color: "white", }} onClick={(event) => {
|
<div style={{ textDecoration: "none", color: "white", }} onClick={(event) => {
|
||||||
clickedApp(hit)
|
clickedApp(hit)
|
||||||
@@ -10568,6 +10581,9 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
const CustomAppHits = connectHits(AppHits)
|
const CustomAppHits = connectHits(AppHits)
|
||||||
|
|
||||||
var shuffleToolsApp = apps.find((app) => app.name === "Shuffle Tools")
|
var shuffleToolsApp = apps.find((app) => app.name === "Shuffle Tools")
|
||||||
|
if (shuffleToolsApp !== undefined && shuffleToolsApp !== null) {
|
||||||
|
shuffleToolsApp = JSON.parse(JSON.stringify(shuffleToolsApp))
|
||||||
|
}
|
||||||
|
|
||||||
var viewedApps = []
|
var viewedApps = []
|
||||||
return (
|
return (
|
||||||
@@ -10620,24 +10636,24 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
<div style={{
|
<div style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
}}>
|
}}>
|
||||||
<ParsedAppPaper small={true} action={"repeat_back_to_me"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"repeat_back_to_me"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"filter_list"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"filter_list"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"execute_python"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"execute_python"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"parse_ioc"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"parse_ioc"} app={shuffleToolsApp} />
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
}}>
|
}}>
|
||||||
<ParsedAppPaper small={true} action={"set_cache_value"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"set_cache_value"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"get_file_meta"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"get_file_meta"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"merge_lists"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"merge_lists"} app={shuffleToolsApp} />
|
||||||
<div style={{marginLeft: 5, }}/>
|
<div style={{marginLeft: 5, }}/>
|
||||||
<ParsedAppPaper small={true} action={"send_sms_shuffle"} app={JSON.parse(JSON.stringify(shuffleToolsApp))} />
|
<ParsedAppPaper small={true} action={"send_sms_shuffle"} app={shuffleToolsApp} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
@@ -16242,7 +16258,7 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
|
|
||||||
{!distributedFromParent ?
|
{!distributedFromParent ?
|
||||||
isCorrectOrg ? null :
|
isCorrectOrg ? null :
|
||||||
<Typography variant="body2">
|
<Typography variant="body2" style={{marginLeft: 10, }}>
|
||||||
<b>Warning</b>: Change <span
|
<b>Warning</b>: Change <span
|
||||||
style={{color: "#FF8544", cursor: "pointer", pointerEvents: "auto", }}
|
style={{color: "#FF8544", cursor: "pointer", pointerEvents: "auto", }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -16313,7 +16329,7 @@ const releaseToConnectLabel = "Release to Connect"
|
|||||||
>Active Organization</span> to edit this Workflow.
|
>Active Organization</span> to edit this Workflow.
|
||||||
</Typography>
|
</Typography>
|
||||||
:
|
:
|
||||||
<Typography variant="body2" color="textSecondary">
|
<Typography variant="body2" color="textSecondary" style={{marginLeft: 10, }}>
|
||||||
Warning: This workflow is controlled by your parent org and may not be editable.
|
Warning: This workflow is controlled by your parent org and may not be editable.
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
const [authenticationType, setAuthenticationType] = React.useState("");
|
const [authenticationType, setAuthenticationType] = React.useState("");
|
||||||
const [appAuthentication, setAppAuthentication] = useState([]);
|
const [appAuthentication, setAppAuthentication] = useState([]);
|
||||||
const [selectedMeta, setSelectedMeta] = useState(undefined);
|
const [selectedMeta, setSelectedMeta] = useState(undefined);
|
||||||
|
const [appLoaded, setAppLoaded] = useState(false);
|
||||||
const [selectedAction, setSelectedAction] = useState(
|
const [selectedAction, setSelectedAction] = useState(
|
||||||
{
|
{
|
||||||
"app_name": selectedAppData.name,
|
"app_name": selectedAppData.name,
|
||||||
@@ -258,6 +259,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
parsedapp.body === undefined ? parsedapp : JSON.parse(parsedapp.body);
|
parsedapp.body === undefined ? parsedapp : JSON.parse(parsedapp.body);
|
||||||
|
|
||||||
setOpenapi(data);
|
setOpenapi(data);
|
||||||
|
setAppLoaded(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAppAuthenticationType = (selectedAppData) => {
|
const handleAppAuthenticationType = (selectedAppData) => {
|
||||||
@@ -773,7 +775,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const skeletonLoader = (
|
const SkeletonLoader = () => (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -892,6 +894,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const AuthenticationData = (props) => {
|
const AuthenticationData = (props) => {
|
||||||
const selectedApp = props.app;
|
const selectedApp = props.app;
|
||||||
|
|
||||||
@@ -1756,7 +1759,10 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper isLoggedIn={isLoggedIn} isLoaded={isLoaded}>
|
<Wrapper isLoggedIn={isLoggedIn} isLoaded={isLoaded}>
|
||||||
<Suspense fallback={skeletonLoader}>
|
{appLoaded === false ? (
|
||||||
|
<SkeletonLoader />
|
||||||
|
) : (
|
||||||
|
<Suspense fallback={SkeletonLoader}>
|
||||||
{authenticationModal}
|
{authenticationModal}
|
||||||
<ApiExplorer
|
<ApiExplorer
|
||||||
openapi={openapi}
|
openapi={openapi}
|
||||||
@@ -1770,6 +1776,7 @@ const ApiExplorerWrapper = (props) => {
|
|||||||
isLoaded={isLoaded}
|
isLoaded={isLoaded}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ const inputColor = "#383B40";
|
|||||||
const bodyDivStyle = {
|
const bodyDivStyle = {
|
||||||
margin: "auto",
|
margin: "auto",
|
||||||
width: "900px",
|
width: "900px",
|
||||||
|
zoom: 0.8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionListStyle = {
|
const actionListStyle = {
|
||||||
@@ -72,10 +73,11 @@ const actionListStyle = {
|
|||||||
paddingBottom: "10px",
|
paddingBottom: "10px",
|
||||||
paddingTop: "10px",
|
paddingTop: "10px",
|
||||||
marginTop: "5px",
|
marginTop: "5px",
|
||||||
backgroundColor: inputColor,
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
color: "white",
|
color: "white",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
|
|
||||||
|
backgroundColor: theme.palette.platformColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const boxStyle = {
|
const boxStyle = {
|
||||||
@@ -89,7 +91,8 @@ const boxStyle = {
|
|||||||
paddingTop: "30px",
|
paddingTop: "30px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
backgroundColor: surfaceColor,
|
|
||||||
|
backgroundColor: theme.palette.backgroundColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const dividerStyle = {
|
const dividerStyle = {
|
||||||
@@ -5808,9 +5811,11 @@ const AppCreator = (defaultprops) => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
var urlParams = new URLSearchParams(window.location.search);
|
var urlParams = new URLSearchParams(window.location.search)
|
||||||
if (!urlParams.has("id")) {
|
if (urlParams.has("id")) {
|
||||||
window.open(`/apis/${app.id}`, "_blank")
|
window.open(`/apis/${urlParams.get("id")}`, "_blank")
|
||||||
|
} else if (props.match.params.appid !== undefined && props.match.params.appid !== null && props.match.params.appid.length > 0) {
|
||||||
|
window.open(`/apis/${props.match.params.appid}`, "_blank")
|
||||||
} else {
|
} else {
|
||||||
toast.error("Build the app first.")
|
toast.error("Build the app first.")
|
||||||
}
|
}
|
||||||
@@ -6191,7 +6196,7 @@ const AppCreator = (defaultprops) => {
|
|||||||
{testView}
|
{testView}
|
||||||
*/}
|
*/}
|
||||||
|
|
||||||
<div style={{height: 50, padding: 25, display: "flex", marginTop: 35, position: "fixed", bottom: 0, left: 0, width: "100%", backgroundColor: theme.palette?.backgroundColor, borderTop: "1px solid rgba(255,255,255,0.3)",}}>
|
<div style={{height: 50, padding: 15, display: "flex", marginTop: 35, position: "fixed", bottom: 0, left: 0, width: "100%", backgroundColor: theme.palette?.backgroundColor, borderTop: "1px solid rgba(255,255,255,0.3)",}}>
|
||||||
<div style={{width: 450, margin: "auto", display: "flex", textAlign: "center", }}>
|
<div style={{width: 450, margin: "auto", display: "flex", textAlign: "center", }}>
|
||||||
{appDownloadData.length > 0 ?
|
{appDownloadData.length > 0 ?
|
||||||
<Tooltip title="Download the OpenAPI specification for the App" placement="bottom">
|
<Tooltip title="Download the OpenAPI specification for the App" placement="bottom">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useState, useEffect, useContext, useCallback, memo, useMemo, useRef } from "react";
|
import React, { useState, useEffect, useContext, useCallback, memo, useMemo, useRef } from "react";
|
||||||
import theme from "../theme.jsx";
|
import theme from "../theme.jsx";
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import AppGrid from "../components/AppGrid.jsx";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
TextField, Button, Typography, MenuItem, Select, Tabs, Tab, Zoom,
|
TextField, Button, Typography, MenuItem, Select, Tabs, Tab, Zoom,
|
||||||
@@ -75,6 +74,22 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
|||||||
style={paperStyle}
|
style={paperStyle}
|
||||||
onMouseOver={() => setMouseHoverIndex(index)}
|
onMouseOver={() => setMouseHoverIndex(index)}
|
||||||
onMouseOut={() => setMouseHoverIndex(-1)}
|
onMouseOut={() => setMouseHoverIndex(-1)}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
title="View app details"
|
||||||
|
placement="top"
|
||||||
|
componentsProps={{
|
||||||
|
tooltip: {
|
||||||
|
sx: {
|
||||||
|
backgroundColor: "rgba(33, 33, 33, 1)",
|
||||||
|
color: "rgba(241, 241, 241, 1)",
|
||||||
|
fontSize: 14,
|
||||||
|
border: "1px solid rgba(73, 73, 73, 1)",
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
arrow
|
||||||
>
|
>
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
style={{
|
style={{
|
||||||
@@ -111,7 +126,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
|||||||
fontWeight: '400',
|
fontWeight: '400',
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
margin: "12px 0",
|
margin: "12px 0",
|
||||||
fontFamily: theme?.typography?.fontFamily
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
}}>
|
}}>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -207,6 +222,8 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
|||||||
bgcolor: "rgba(93, 93, 93, 1)",
|
bgcolor: "rgba(93, 93, 93, 1)",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
|
onMouseUp={(e) => e.stopPropagation()}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -241,6 +258,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
</Tooltip>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
@@ -263,10 +281,11 @@ const Hits = ({
|
|||||||
const [allActivatedAppIds, setAllActivatedAppIds] = useState([]);
|
const [allActivatedAppIds, setAllActivatedAppIds] = useState([]);
|
||||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
||||||
const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]);
|
const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]);
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
var baseurl = globalUrl;
|
var baseurl = globalUrl;
|
||||||
|
setIsLoading(true)
|
||||||
fetch(baseurl + "/api/v1/me", {
|
fetch(baseurl + "/api/v1/me", {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
@@ -361,7 +380,34 @@ const Hits = ({
|
|||||||
(
|
(
|
||||||
<div>
|
<div>
|
||||||
{hits?.length === 0 && searchQuery.length >= 0 ? (
|
{hits?.length === 0 && searchQuery.length >= 0 ? (
|
||||||
<Typography>No apps found</Typography>
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
minHeight: 400,
|
||||||
|
gap: 16,
|
||||||
|
color: "#F1F1F1",
|
||||||
|
fontFamily: theme?.typography?.fontFamily
|
||||||
|
}}>
|
||||||
|
<SearchIcon style={{ fontSize: 48, color: 'rgba(255, 255, 255, 0.7)' }} />
|
||||||
|
<Typography variant="h6" style={{
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
textAlign: "center"
|
||||||
|
}}>
|
||||||
|
No apps found matching your search criteria
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
style={{
|
||||||
|
color: 'rgba(255, 255, 255, 0.7)',
|
||||||
|
textAlign: "center",
|
||||||
|
maxWidth: 400
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Try adjusting your search terms or filters to find what you're looking for
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -412,6 +458,22 @@ const Hits = ({
|
|||||||
onMouseLeave={() => {
|
onMouseLeave={() => {
|
||||||
setHoverEffect(-1);
|
setHoverEffect(-1);
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
title="View app details"
|
||||||
|
placement="top"
|
||||||
|
componentsProps={{
|
||||||
|
tooltip: {
|
||||||
|
sx: {
|
||||||
|
backgroundColor: "rgba(33, 33, 33, 1)",
|
||||||
|
color: "rgba(241, 241, 241, 1)",
|
||||||
|
fontSize: 14,
|
||||||
|
border: "1px solid rgba(73, 73, 73, 1)",
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
arrow
|
||||||
>
|
>
|
||||||
<ButtonBase style={{
|
<ButtonBase style={{
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
@@ -448,8 +510,9 @@ const Hits = ({
|
|||||||
gap: 6,
|
gap: 6,
|
||||||
fontWeight: '400',
|
fontWeight: '400',
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
margin: "12px 0",
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
fontFamily: theme?.typography?.fontFamily
|
marginTop: 8,
|
||||||
|
marginLeft: 16,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -571,6 +634,8 @@ const Hits = ({
|
|||||||
fontFamily: theme?.typography?.fontFamily,
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
}}
|
}}
|
||||||
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
|
onMouseUp={(e) => e.stopPropagation()}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
handleActivateButton(event, data, "deactivate");
|
handleActivateButton(event, data, "deactivate");
|
||||||
}}>
|
}}>
|
||||||
@@ -588,6 +653,8 @@ const Hits = ({
|
|||||||
fontFamily: theme?.typography?.fontFamily,
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
}}
|
}}
|
||||||
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
|
onMouseUp={(e) => e.stopPropagation()}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
handleActivateButton(event, data, "activate");
|
handleActivateButton(event, data, "activate");
|
||||||
}}
|
}}
|
||||||
@@ -601,6 +668,7 @@ const Hits = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
</Tooltip>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Zoom>
|
</Zoom>
|
||||||
);
|
);
|
||||||
@@ -872,6 +940,42 @@ const filterApps = (apps, searchQuery, selectedCategory, selectedLabel) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LoginPrompt = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
minHeight: 400,
|
||||||
|
gap: 20,
|
||||||
|
color: "#F1F1F1",
|
||||||
|
fontFamily: theme?.typography?.fontFamily
|
||||||
|
}}>
|
||||||
|
<Typography variant="h6" style={{ fontFamily: theme?.typography?.fontFamily }}>
|
||||||
|
Log in to see your organization's apps
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => navigate("/login")}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#FF8544",
|
||||||
|
color: "#1A1A1A",
|
||||||
|
textTransform: "none",
|
||||||
|
fontFamily: theme?.typography?.fontFamily,
|
||||||
|
fontSize: 16,
|
||||||
|
padding: "10px 20px",
|
||||||
|
borderRadius: 4,
|
||||||
|
fontWeight: 600
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Log In
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// Add this new component for the app skeleton
|
// Add this new component for the app skeleton
|
||||||
const AppSkeleton = () => {
|
const AppSkeleton = () => {
|
||||||
return (
|
return (
|
||||||
@@ -1761,7 +1865,7 @@ const Apps2 = (props) => {
|
|||||||
<div style={boxStyle}>
|
<div style={boxStyle}>
|
||||||
<div style={{ display: "flex", flexDirection: "row", width: "100%", justifyContent: "space-between" }}>
|
<div style={{ display: "flex", flexDirection: "row", width: "100%", justifyContent: "space-between" }}>
|
||||||
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
|
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
|
||||||
Apps
|
{currTab === 0 ? "Org" : currTab === 1 ? "Your" : "Discover"} Apps
|
||||||
</Typography>
|
</Typography>
|
||||||
{isCloud ? null : (
|
{isCloud ? null : (
|
||||||
<span style={{ display: "flex", gap: 15 }}>
|
<span style={{ display: "flex", gap: 15 }}>
|
||||||
@@ -1895,6 +1999,7 @@ const Apps2 = (props) => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
placeholder="Search for apps"
|
placeholder="Search for apps"
|
||||||
|
disabled={!isLoggedIn}
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
id="shuffle_search_field"
|
id="shuffle_search_field"
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
@@ -1945,6 +2050,7 @@ const Apps2 = (props) => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={selectedCategory}
|
value={selectedCategory}
|
||||||
onChange={handleCategoryChange}
|
onChange={handleCategoryChange}
|
||||||
|
disabled={!isLoggedIn}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
multiple
|
multiple
|
||||||
style={{
|
style={{
|
||||||
@@ -2009,6 +2115,7 @@ const Apps2 = (props) => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={selectedLabel}
|
value={selectedLabel}
|
||||||
onChange={handleLabelChange}
|
onChange={handleLabelChange}
|
||||||
|
disabled={!isLoggedIn}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
multiple
|
multiple
|
||||||
style={{
|
style={{
|
||||||
@@ -2067,6 +2174,7 @@ const Apps2 = (props) => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleCreateApp}
|
onClick={handleCreateApp}
|
||||||
|
disabled={!isLoggedIn}
|
||||||
style={{
|
style={{
|
||||||
height: "100%",
|
height: "100%",
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -2092,6 +2200,7 @@ const Apps2 = (props) => {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<LoadingGrid />
|
<LoadingGrid />
|
||||||
) : (
|
) : (
|
||||||
|
isLoggedIn && !isLoading ? (
|
||||||
<>
|
<>
|
||||||
{appsToShow?.length > 0 && appsToShow !== undefined && !isLoading ? (
|
{appsToShow?.length > 0 && appsToShow !== undefined && !isLoading ? (
|
||||||
<div style={{
|
<div style={{
|
||||||
@@ -2137,6 +2246,9 @@ const Apps2 = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
) : (
|
||||||
|
<LoginPrompt />
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -2147,6 +2259,7 @@ const Apps2 = (props) => {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<LoadingGrid />
|
<LoadingGrid />
|
||||||
) : (
|
) : (
|
||||||
|
isLoggedIn && !isLoading ? (
|
||||||
<>
|
<>
|
||||||
{appsToShow?.length > 0 && appsToShow !== undefined ? (
|
{appsToShow?.length > 0 && appsToShow !== undefined ? (
|
||||||
<div style={{
|
<div style={{
|
||||||
@@ -2182,6 +2295,9 @@ const Apps2 = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
) : (
|
||||||
|
<LoginPrompt />
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -716,6 +716,8 @@ const Workflows2 = (props) => {
|
|||||||
const [videoViewOpen, setVideoViewOpen] = React.useState(false)
|
const [videoViewOpen, setVideoViewOpen] = React.useState(false)
|
||||||
const [gettingStartedItems, setGettingStartedItems] = React.useState([])
|
const [gettingStartedItems, setGettingStartedItems] = React.useState([])
|
||||||
const [selectedWorkflowIndexes, setSelectedWorkflowIndexes] = React.useState([])
|
const [selectedWorkflowIndexes, setSelectedWorkflowIndexes] = React.useState([])
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [pageSize, setPageSize] = React.useState(100);
|
||||||
const [highlightIds, setHighlightIds] = React.useState([])
|
const [highlightIds, setHighlightIds] = React.useState([])
|
||||||
|
|
||||||
const [apps, setApps] = React.useState([]);
|
const [apps, setApps] = React.useState([]);
|
||||||
@@ -751,15 +753,6 @@ const Workflows2 = (props) => {
|
|||||||
navigate(`${location.pathname}?${queryParams.toString()}`);
|
navigate(`${location.pathname}?${queryParams.toString()}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (currTab === 2) {
|
|
||||||
setIsLoadingPublicWorkflow(true);
|
|
||||||
// Simulate loading time for the Algolia search results
|
|
||||||
setTimeout(() => {
|
|
||||||
setIsLoadingPublicWorkflow(false);
|
|
||||||
}, 2500);
|
|
||||||
}
|
|
||||||
}, [currTab])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1319,8 +1312,17 @@ const Workflows2 = (props) => {
|
|||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((responseJson) => {
|
.then((responseJson) => {
|
||||||
console.log("Response : /api/v1/workflows", responseJson)
|
if (responseJson !== undefined && responseJson !== null) {
|
||||||
if (responseJson !== undefined) {
|
if (responseJson.success === false) {
|
||||||
|
} else if (responseJson.length === 0) {
|
||||||
|
// When there are no workflows, we can set the loading to false
|
||||||
|
setIsLoadingWorkflow(false)
|
||||||
|
if (currTab !== 2) {
|
||||||
|
toast("No workflows found. Showing workflow discovery")
|
||||||
|
setCurrTab(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var newarray = []
|
var newarray = []
|
||||||
for (var wfkey in responseJson) {
|
for (var wfkey in responseJson) {
|
||||||
const wf = responseJson[wfkey]
|
const wf = responseJson[wfkey]
|
||||||
@@ -2476,6 +2478,7 @@ const Workflows2 = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? "2px solid #40E0D0" : "inherit", borderRadius: theme.palette?.borderRadius, backgroundColor: "#212121", fontFamily: theme?.typography?.fontFamily }}>
|
<div style={{ width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? "2px solid #40E0D0" : "inherit", borderRadius: theme.palette?.borderRadius, backgroundColor: "#212121", fontFamily: theme?.typography?.fontFamily }}>
|
||||||
<Paper square style={paperAppStyle}>
|
<Paper square style={paperAppStyle}>
|
||||||
@@ -2530,7 +2533,7 @@ const Workflows2 = (props) => {
|
|||||||
maxWidth: 310,
|
maxWidth: 310,
|
||||||
padding: "12px 0",
|
padding: "12px 0",
|
||||||
}}>
|
}}>
|
||||||
{(data?.image !== undefined || data?.image_url !== undefined) ? (
|
{(data?.image !== undefined || (data?.image_url !== undefined && data?.image_url.length > 0)) ? (
|
||||||
<div style={{
|
<div style={{
|
||||||
marginBottom: 15,
|
marginBottom: 15,
|
||||||
borderRadius: theme.palette?.borderRadius,
|
borderRadius: theme.palette?.borderRadius,
|
||||||
@@ -3364,7 +3367,15 @@ const Workflows2 = (props) => {
|
|||||||
className={classes.datagrid}
|
className={classes.datagrid}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
pageSize={100}
|
page={page}
|
||||||
|
onPageChange={(newPage) => {
|
||||||
|
setPage(newPage)
|
||||||
|
}}
|
||||||
|
pageSize={pageSize}
|
||||||
|
onPageSizeChange={(newPageSize) => {
|
||||||
|
setPageSize(newPageSize);
|
||||||
|
}}
|
||||||
|
rowsPerPageOptions={[25, 50, 100, 150]}
|
||||||
checkboxSelection
|
checkboxSelection
|
||||||
autoHeight
|
autoHeight
|
||||||
density="standard"
|
density="standard"
|
||||||
@@ -3955,7 +3966,7 @@ const Workflows2 = (props) => {
|
|||||||
setIsLoadingWorkflow(false);
|
setIsLoadingWorkflow(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [currTab, workflows, userdata, filteredWorkflows])
|
}, [currTab, workflows, userdata, filteredWorkflows, filters])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -4243,7 +4254,7 @@ const Workflows2 = (props) => {
|
|||||||
margin: "auto",
|
margin: "auto",
|
||||||
}}>
|
}}>
|
||||||
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
|
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
|
||||||
Workflows
|
{currTab === 0 ? "Org" : currTab === 1 ? "Your" : "Discover"} Workflows
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<div style={{ borderBottom: '1px solid gray', marginBottom: 30 }}>
|
<div style={{ borderBottom: '1px solid gray', marginBottom: 30 }}>
|
||||||
@@ -4258,21 +4269,21 @@ const Workflows2 = (props) => {
|
|||||||
TabIndicatorProps={{ style: { display: 'none' } }}
|
TabIndicatorProps={{ style: { display: 'none' } }}
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
label="Organization Apps"
|
label="Organization Workflows"
|
||||||
style={{
|
style={{
|
||||||
...tabStyle,
|
...tabStyle,
|
||||||
...(currTab === 0 ? tabActive : {})
|
...(currTab === 0 ? tabActive : {})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
label="My Apps"
|
label="My Workflows"
|
||||||
style={{
|
style={{
|
||||||
...tabStyle,
|
...tabStyle,
|
||||||
...(currTab === 1 ? tabActive : {})
|
...(currTab === 1 ? tabActive : {})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
label="Discover Apps"
|
label="Discover Workflows"
|
||||||
style={{
|
style={{
|
||||||
...tabStyle,
|
...tabStyle,
|
||||||
marginRight: 0,
|
marginRight: 0,
|
||||||
|
|||||||
Executable → Regular
+18
-25
@@ -1,36 +1,29 @@
|
|||||||
FROM golang:1.22 as builder
|
FROM golang:1.22 as builder
|
||||||
|
|
||||||
RUN mkdir /app
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY orborus.go /app/orborus.go
|
# COPY go.* ./
|
||||||
#COPY go.mod /app/go.mod
|
|
||||||
#COPY go.sum /app/go.sum
|
|
||||||
RUN go mod init orborus
|
RUN go mod init orborus
|
||||||
|
|
||||||
RUN go get github.com/docker/docker/api/types
|
RUN go get \
|
||||||
RUN go get github.com/docker/docker/api/types/container
|
github.com/docker/docker/api/types \
|
||||||
#RUN go get github.com/docker/docker/client
|
github.com/docker/docker/api/types/container \
|
||||||
RUN go get github.com/mackerelio/go-osstat/cpu
|
github.com/mackerelio/go-osstat/cpu \
|
||||||
RUN go get github.com/mackerelio/go-osstat/memory
|
github.com/mackerelio/go-osstat/memory \
|
||||||
RUN go get github.com/satori/go.uuid
|
github.com/satori/go.uuid \
|
||||||
RUN go get github.com/shuffle/shuffle-shared
|
github.com/shuffle/shuffle-shared \
|
||||||
RUN go get github.com/shirou/gopsutil
|
github.com/shirou/gopsutil
|
||||||
RUN go get k8s.io/client-go
|
|
||||||
RUN go get k8s.io/apimachinery
|
|
||||||
|
|
||||||
RUN go get
|
COPY orborus.go .
|
||||||
RUN go mod tidy
|
|
||||||
RUN go build
|
RUN go mod tidy && \
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o orborus .
|
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o orborus .
|
||||||
|
|
||||||
FROM alpine:3.15.0
|
FROM alpine:3.15.0
|
||||||
RUN apk add --no-cache bash tzdata
|
RUN apk add --no-cache bash tzdata
|
||||||
COPY --from=builder /app/ /
|
COPY --from=builder /app/orborus /
|
||||||
|
ENV ENVIRONMENT_NAME=Shuffle \
|
||||||
ENV ENVIRONMENT_NAME=Shuffle
|
BASE_URL=http://shuffle-backend:5001 \
|
||||||
ENV BASE_URL=http://shuffle-backend:5001
|
DOCKER_API_VERSION=1.40 \
|
||||||
ENV DOCKER_API_VERSION=1.40
|
SHUFFLE_OPENSEARCH_URL=https://opensearch:9200
|
||||||
ENV SHUFFLE_OPENSEARCH_URL=https://opensearch:9200
|
|
||||||
|
|
||||||
CMD ["./orborus"]
|
CMD ["./orborus"]
|
||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
FROM golang:1.22 as builder
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY orborus.go /app/orborus.go
|
||||||
|
#COPY go.mod /app/go.mod
|
||||||
|
#COPY go.sum /app/go.sum
|
||||||
|
RUN go mod init orborus
|
||||||
|
|
||||||
|
RUN go get github.com/docker/docker/api/types
|
||||||
|
RUN go get github.com/docker/docker/api/types/container
|
||||||
|
#RUN go get github.com/docker/docker/client
|
||||||
|
RUN go get github.com/mackerelio/go-osstat/cpu
|
||||||
|
RUN go get github.com/mackerelio/go-osstat/memory
|
||||||
|
RUN go get github.com/satori/go.uuid
|
||||||
|
RUN go get github.com/shuffle/shuffle-shared
|
||||||
|
RUN go get github.com/shirou/gopsutil
|
||||||
|
# RUN go get k8s.io/client-go
|
||||||
|
# RUN go get k8s.io/apimachinery
|
||||||
|
|
||||||
|
RUN go get
|
||||||
|
RUN go mod tidy
|
||||||
|
RUN go build
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o orborus .
|
||||||
|
|
||||||
|
FROM alpine:3.15.0
|
||||||
|
RUN apk add --no-cache bash tzdata
|
||||||
|
COPY --from=builder /app/ /
|
||||||
|
|
||||||
|
ENV ENVIRONMENT_NAME=Shuffle
|
||||||
|
ENV BASE_URL=http://shuffle-backend:5001
|
||||||
|
ENV DOCKER_API_VERSION=1.40
|
||||||
|
ENV SHUFFLE_OPENSEARCH_URL=https://opensearch:9200
|
||||||
|
|
||||||
|
CMD ["./orborus"]
|
||||||
@@ -10,7 +10,7 @@ require (
|
|||||||
github.com/docker/docker v27.0.2+incompatible
|
github.com/docker/docker v27.0.2+incompatible
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.5.0
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shuffle/shuffle-shared v0.6.90
|
github.com/shuffle/shuffle-shared v0.6.93
|
||||||
k8s.io/api v0.30.2
|
k8s.io/api v0.30.2
|
||||||
k8s.io/apimachinery v0.30.2
|
k8s.io/apimachinery v0.30.2
|
||||||
)
|
)
|
||||||
@@ -95,14 +95,14 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.30.0 // indirect
|
go.opentelemetry.io/otel/trace v1.30.0 // indirect
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
golang.org/x/crypto v0.31.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.17.0 // indirect
|
||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.29.0 // indirect
|
||||||
golang.org/x/oauth2 v0.21.0 // indirect
|
golang.org/x/oauth2 v0.21.0 // indirect
|
||||||
golang.org/x/sync v0.10.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/term v0.27.0 // indirect
|
golang.org/x/term v0.24.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
|
|||||||
@@ -366,8 +366,8 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0
|
|||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -443,8 +443,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -473,16 +473,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -494,8 +494,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
|
|||||||
@@ -199,7 +199,9 @@ func skipCheckInCleanup(name string) bool {
|
|||||||
strings.HasPrefix(name, "orborus") ||
|
strings.HasPrefix(name, "orborus") ||
|
||||||
strings.HasPrefix(name, "shuffle-orborus") ||
|
strings.HasPrefix(name, "shuffle-orborus") ||
|
||||||
strings.HasPrefix(name, "opensearch") ||
|
strings.HasPrefix(name, "opensearch") ||
|
||||||
strings.HasPrefix(name, "shuffle-opensearch")
|
strings.HasPrefix(name, "shuffle-opensearch") ||
|
||||||
|
strings.HasPrefix(name, "memcached") ||
|
||||||
|
strings.HasPrefix(name, "shuffle-memcached")
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanupExistingNodes(ctx context.Context) error {
|
func cleanupExistingNodes(ctx context.Context) error {
|
||||||
@@ -608,8 +610,7 @@ func deployServiceWorkers(image string) {
|
|||||||
Condition: swarm.RestartPolicyConditionOnFailure,
|
Condition: swarm.RestartPolicyConditionOnFailure,
|
||||||
},
|
},
|
||||||
Placement: &swarm.Placement{
|
Placement: &swarm.Placement{
|
||||||
Constraints: []string{
|
Constraints: []string{},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -2152,7 +2153,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" && os.Getenv("SHUFFLE_SCALE_REPLICAS") == "" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" && os.Getenv("SHUFFLE_SCALE_REPLICAS") == "" {
|
||||||
go AutoScale(ctx)
|
// go AutoScale(ctx)
|
||||||
}
|
}
|
||||||
hasStarted = true
|
hasStarted = true
|
||||||
}
|
}
|
||||||
@@ -2297,11 +2298,20 @@ func main() {
|
|||||||
} else if incRequest.Type == "START_TENZIR" {
|
} else if incRequest.Type == "START_TENZIR" {
|
||||||
log.Printf("[INFO] Got job to start tenzir")
|
log.Printf("[INFO] Got job to start tenzir")
|
||||||
|
|
||||||
|
// Manual command = overrides to allow starting of Tenzir from the frontend anyway.
|
||||||
|
os.Setenv("SHUFFLE_SKIP_PIPELINES", "false")
|
||||||
|
tenzirDisabled = false
|
||||||
|
|
||||||
|
// Removed either way
|
||||||
|
toBeRemoved.Data = append(toBeRemoved.Data, incRequest)
|
||||||
|
|
||||||
err := deployTenzirNode()
|
err := deployTenzirNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(fmt.Sprintf("%s", err), "node available") {
|
if strings.Contains(fmt.Sprintf("%s", err), "node available") {
|
||||||
toBeRemoved.Data = append(toBeRemoved.Data, incRequest)
|
// Disabling until UI is updated
|
||||||
} else {
|
os.Setenv("SHUFFLE_SKIP_PIPELINES", "true")
|
||||||
|
tenzirDisabled = true
|
||||||
|
|
||||||
log.Printf("[ERROR] Failed to start tenzir, reason: %s", err)
|
log.Printf("[ERROR] Failed to start tenzir, reason: %s", err)
|
||||||
err = shuffle.CreateOrgNotification(
|
err = shuffle.CreateOrgNotification(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -2317,9 +2327,6 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
toBeRemoved.Data = append(toBeRemoved.Data, incRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -2620,7 +2627,7 @@ func handlePipeline(incRequest shuffle.ExecutionRequest) error {
|
|||||||
func deployTenzirNode() error {
|
func deployTenzirNode() error {
|
||||||
if os.Getenv("SHUFFLE_SKIP_PIPELINES") == "false" || os.Getenv("SHUFFLE_PIPELINE_ENABLED") == "true" {
|
if os.Getenv("SHUFFLE_SKIP_PIPELINES") == "false" || os.Getenv("SHUFFLE_PIPELINE_ENABLED") == "true" {
|
||||||
// return errors.New("Pipelines are disabled by user with SHUFFLE_SKIP_PIPELINES")
|
// return errors.New("Pipelines are disabled by user with SHUFFLE_SKIP_PIPELINES")
|
||||||
log.Printf("[INFO] Pipelines are enabled by user")
|
//log.Printf("[INFO] Pipelines are enabled by user")
|
||||||
} else {
|
} else {
|
||||||
return errors.New("Pipelines are disabled by user with SHUFFLE_SKIP_PIPELINES")
|
return errors.New("Pipelines are disabled by user with SHUFFLE_SKIP_PIPELINES")
|
||||||
}
|
}
|
||||||
@@ -2637,7 +2644,7 @@ func deployTenzirNode() error {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
cacheKey := "tenzir-key"
|
cacheKey := "tenzir-key"
|
||||||
|
|
||||||
imageName := "tenzir/tenzir:latest"
|
imageName := "frikky/shuffle:tenzir"
|
||||||
containerName := "tenzir-node"
|
containerName := "tenzir-node"
|
||||||
containerStartOptions := container.StartOptions{}
|
containerStartOptions := container.StartOptions{}
|
||||||
_, err = shuffle.GetCache(ctx, cacheKey)
|
_, err = shuffle.GetCache(ctx, cacheKey)
|
||||||
@@ -2822,9 +2829,13 @@ func createAndStartTenzirNode(ctx context.Context, containerName, imageName stri
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Is this necessary? Seems to screw up networking:
|
||||||
|
// conflicting options: hostname and the network mode
|
||||||
|
/*
|
||||||
if isKubernetes != "true" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" {
|
if isKubernetes != "true" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" {
|
||||||
hostConfig.NetworkMode = container.NetworkMode(fmt.Sprintf("container:%s", containerId))
|
hostConfig.NetworkMode = container.NetworkMode(fmt.Sprintf("container:%s", containerId))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
resp, err := dockercli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName)
|
resp, err := dockercli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3455,6 +3466,7 @@ func sendPipelineHealthStatus() (shuffle.LakeConfig, error) {
|
|||||||
if (!strings.Contains(err.Error(), "SHUFFLE_SKIP_PIPELINES") && !strings.Contains(err.Error(), "Kubernetes not implemented for Tenzir node")) && !strings.Contains(err.Error(), "Tenzir Node is already running") && !strings.Contains(err.Error(), "docker daemon") {
|
if (!strings.Contains(err.Error(), "SHUFFLE_SKIP_PIPELINES") && !strings.Contains(err.Error(), "Kubernetes not implemented for Tenzir node")) && !strings.Contains(err.Error(), "Tenzir Node is already running") && !strings.Contains(err.Error(), "docker daemon") {
|
||||||
|
|
||||||
log.Printf("[ERROR] Tenzir node connection problem: %s", err)
|
log.Printf("[ERROR] Tenzir node connection problem: %s", err)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tenzirDisabled = true
|
tenzirDisabled = true
|
||||||
log.Printf("[ERROR] Disabling pipelines: %s. You will need to restart the Orborus to fix this.", err)
|
log.Printf("[ERROR] Disabling pipelines: %s. You will need to restart the Orborus to fix this.", err)
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ import (
|
|||||||
dockerclient "github.com/docker/docker/client"
|
dockerclient "github.com/docker/docker/client"
|
||||||
|
|
||||||
// This is for automatic removal of certain code :)
|
// This is for automatic removal of certain code :)
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
|
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ var autoDeploy = map[string]string{
|
|||||||
"shuffle-tools:1.2.0": "frikky/shuffle:shuffle-tools_1.2.0",
|
"shuffle-tools:1.2.0": "frikky/shuffle:shuffle-tools_1.2.0",
|
||||||
"shuffle-subflow:1.0.0": "frikky/shuffle:shuffle-subflow_1.0.0",
|
"shuffle-subflow:1.0.0": "frikky/shuffle:shuffle-subflow_1.0.0",
|
||||||
"shuffle-subflow:1.1.0": "frikky/shuffle:shuffle-subflow_1.1.0",
|
"shuffle-subflow:1.1.0": "frikky/shuffle:shuffle-subflow_1.1.0",
|
||||||
"shuffle-tools-fork:1.0.0": "frikky/shuffle:shuffle-tools-fork_1.0.0",
|
// "shuffle-tools-fork:1.0.0": "frikky/shuffle:shuffle-tools-fork_1.0.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
//"testing:1.0.0": "frikky/shuffle:testing_1.0.0",
|
//"testing:1.0.0": "frikky/shuffle:testing_1.0.0",
|
||||||
@@ -321,11 +321,11 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
|
|||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
||||||
log.Printf("[DEBUG][%s] NOT cleaning up containers. IDS: %d, CLEANUP env: %s", workflowExecution.ExecutionId, 0, cleanupEnv)
|
log.Printf("[DEBUG][%s] NOT cleaning up containers. IDS: %d, CLEANUP env: %s", workflowExecution.ExecutionId, 0, cleanupEnv)
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(reason) > 0 && len(nodeId) > 0 {
|
if len(reason) > 0 && len(nodeId) > 0 {
|
||||||
@@ -393,7 +393,7 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
|
|||||||
|
|
||||||
func int32Ptr(i int32) *int32 { return &i }
|
func int32Ptr(i int32) *int32 { return &i }
|
||||||
|
|
||||||
// ** ***/
|
// ** STARTREMOVE ***/
|
||||||
func deployk8sApp(image string, identifier string, env []string) error {
|
func deployk8sApp(image string, identifier string, env []string) error {
|
||||||
if len(os.Getenv("KUBERNETES_NAMESPACE")) > 0 {
|
if len(os.Getenv("KUBERNETES_NAMESPACE")) > 0 {
|
||||||
kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
||||||
@@ -631,7 +631,7 @@ func deployk8sApp(image string, identifier string, env []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//** ***/
|
//** ENDREMOVE ***/
|
||||||
|
|
||||||
// Deploys the internal worker whenever something happens
|
// Deploys the internal worker whenever something happens
|
||||||
func deployApp(cli *dockerclient.Client, image string, identifier string, env []string, workflowExecution shuffle.WorkflowExecution, action shuffle.Action) error {
|
func deployApp(cli *dockerclient.Client, image string, identifier string, env []string, workflowExecution shuffle.WorkflowExecution, action shuffle.Action) error {
|
||||||
@@ -772,7 +772,7 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
|
|
||||||
appName := strings.Replace(identifier, fmt.Sprintf("_%s", action.ID), "", -1)
|
appName := strings.Replace(identifier, fmt.Sprintf("_%s", action.ID), "", -1)
|
||||||
@@ -802,14 +802,14 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ** ***/
|
// ** STARTREMOVE ***/
|
||||||
exposedPort = 80
|
exposedPort = 80
|
||||||
err = findAppInfoKubernetes(image, appName, env)
|
err = findAppInfoKubernetes(image, appName, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ERROR] Failed finding and creating port for %s: %s", appName, err)
|
log.Printf("[ERROR] Failed finding and creating port for %s: %s", appName, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// ** ***/
|
// ** ENDREMOVE ***/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -852,7 +852,7 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
// Max 10% CPU every second
|
// Max 10% CPU every second
|
||||||
//CPUShares: 128,
|
//CPUShares: 128,
|
||||||
@@ -2404,7 +2404,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if workflowExecution.Status == "WAITING" && (os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm") {
|
if workflowExecution.Status == "WAITING" && (os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm") {
|
||||||
log.Printf("[INFO][%s] Workflow execution is waiting while in swarm. Sending info to backend to ensure execution stops.", workflowExecution.ExecutionId)
|
log.Printf("[INFO][%s] Workflow execution is waiting while in swarm. Sending info to backend to ensure execution stops.", workflowExecution.ExecutionId)
|
||||||
|
|
||||||
@@ -2416,7 +2416,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
shutdown(*workflowExecution, "", "", false)
|
shutdown(*workflowExecution, "", "", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
} else {
|
} else {
|
||||||
if strings.Contains(strings.ToLower(fmt.Sprintf("%s", err)), "already been ran") || strings.Contains(strings.ToLower(fmt.Sprintf("%s", err)), "already finished") {
|
if strings.Contains(strings.ToLower(fmt.Sprintf("%s", err)), "already been ran") || strings.Contains(strings.ToLower(fmt.Sprintf("%s", err)), "already finished") {
|
||||||
log.Printf("[ERROR][%s] Skipping rerun of action result as it's already been ran: %s", workflowExecution.ExecutionId)
|
log.Printf("[ERROR][%s] Skipping rerun of action result as it's already been ran: %s", workflowExecution.ExecutionId)
|
||||||
@@ -2501,7 +2501,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
finished := shuffle.ValidateFinished(ctx, -1, *workflowExecution)
|
finished := shuffle.ValidateFinished(ctx, -1, *workflowExecution)
|
||||||
if !finished {
|
if !finished {
|
||||||
@@ -2516,7 +2516,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
sendResult(*workflowExecution, shutdownData)
|
sendResult(*workflowExecution, shutdownData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[INFO][%s] Skipping setexec with status %s", workflowExecution.ExecutionId, workflowExecution.Status)
|
log.Printf("[INFO][%s] Skipping setexec with status %s", workflowExecution.ExecutionId, workflowExecution.Status)
|
||||||
|
|
||||||
@@ -2536,12 +2536,12 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
|
|
||||||
func sendSelfRequest(actionResult shuffle.ActionResult) {
|
func sendSelfRequest(actionResult shuffle.ActionResult) {
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
||||||
log.Printf("[INFO][%s] Not sending self request info since source is default (not swarm)", actionResult.ExecutionId)
|
log.Printf("[INFO][%s] Not sending self request info since source is default (not swarm)", actionResult.ExecutionId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
data, err := json.Marshal(actionResult)
|
data, err := json.Marshal(actionResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2680,11 +2680,11 @@ func validateFinished(workflowExecution shuffle.WorkflowExecution) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
|
||||||
requestsSent += 1
|
requestsSent += 1
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
log.Printf("[DEBUG][%s] Should send full result to %s", workflowExecution.ExecutionId, baseUrl)
|
log.Printf("[DEBUG][%s] Should send full result to %s", workflowExecution.ExecutionId, baseUrl)
|
||||||
|
|
||||||
@@ -2769,7 +2769,7 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) {
|
|||||||
// GetLocalIP returns the non loopback local IP of the host
|
// GetLocalIP returns the non loopback local IP of the host
|
||||||
func getLocalIP() string {
|
func getLocalIP() string {
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("IS_KUBERNETES") == "true" {
|
if os.Getenv("IS_KUBERNETES") == "true" {
|
||||||
return "shuffle-workers"
|
return "shuffle-workers"
|
||||||
}
|
}
|
||||||
@@ -2836,7 +2836,7 @@ func getLocalIP() string {
|
|||||||
return foundIP
|
return foundIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
addrs, err := net.InterfaceAddrs()
|
addrs, err := net.InterfaceAddrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2887,7 +2887,7 @@ func webserverSetup(workflowExecution shuffle.WorkflowExecution) net.Listener {
|
|||||||
|
|
||||||
log.Printf("[DEBUG] OLD HOSTNAME: %s", appCallbackUrl)
|
log.Printf("[DEBUG] OLD HOSTNAME: %s", appCallbackUrl)
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
log.Printf("[DEBUG] Starting webserver (1) on port %d with hostname: %s", baseport, hostname)
|
log.Printf("[DEBUG] Starting webserver (1) on port %d with hostname: %s", baseport, hostname)
|
||||||
|
|
||||||
@@ -2907,7 +2907,7 @@ func webserverSetup(workflowExecution shuffle.WorkflowExecution) net.Listener {
|
|||||||
|
|
||||||
return listener
|
return listener
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
port := listener.Addr().(*net.TCPAddr).Port
|
port := listener.Addr().(*net.TCPAddr).Port
|
||||||
// Set the port environment variable
|
// Set the port environment variable
|
||||||
@@ -2958,7 +2958,7 @@ func findActiveSwarmNodes(dockercli *dockerclient.Client) (int64, error) {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
func deploySwarmService(dockercli *dockerclient.Client, name, image string, deployport int) error {
|
func deploySwarmService(dockercli *dockerclient.Client, name, image string, deployport int) error {
|
||||||
log.Printf("[DEBUG] Deploying service for %s to swarm on port %d", name, deployport)
|
log.Printf("[DEBUG] Deploying service for %s to swarm on port %d", name, deployport)
|
||||||
//containerName := fmt.Sprintf("shuffle-worker-%s", parsedUuid)
|
//containerName := fmt.Sprintf("shuffle-worker-%s", parsedUuid)
|
||||||
@@ -3128,10 +3128,10 @@ func deploySwarmService(dockercli *dockerclient.Client, name, image string, depl
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
// Runs data discovery
|
// Runs data discovery
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
|
|
||||||
func findAppInfoKubernetes(image, name string, env []string) error {
|
func findAppInfoKubernetes(image, name string, env []string) error {
|
||||||
clientset, _, err := shuffle.GetKubernetesClient()
|
clientset, _, err := shuffle.GetKubernetesClient()
|
||||||
@@ -3291,7 +3291,7 @@ func findAppInfo(image, name string) (int, error) {
|
|||||||
return exposedPort, nil
|
return exposedPort, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
func sendAppRequest(ctx context.Context, incomingUrl, appName string, port int, action *shuffle.Action, workflowExecution *shuffle.WorkflowExecution) error {
|
func sendAppRequest(ctx context.Context, incomingUrl, appName string, port int, action *shuffle.Action, workflowExecution *shuffle.WorkflowExecution) error {
|
||||||
parsedRequest := shuffle.OrborusExecutionRequest{
|
parsedRequest := shuffle.OrborusExecutionRequest{
|
||||||
@@ -3691,11 +3691,11 @@ func getStreamResultsWrapper(client *http.Client, req *http.Request, workflowExe
|
|||||||
|
|
||||||
// Initial loop etc
|
// Initial loop etc
|
||||||
func main() {
|
func main() {
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
logsDisabled = "true"
|
logsDisabled = "true"
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
// Elasticsearch necessary to ensure we'ren ot running with Datastore configurations for minimal/maximal data sizes
|
// Elasticsearch necessary to ensure we'ren ot running with Datastore configurations for minimal/maximal data sizes
|
||||||
// Recursive import kind of :)
|
// Recursive import kind of :)
|
||||||
_, err := shuffle.RunInit(*shuffle.GetDatastore(), *shuffle.GetStorage(), "", "worker", true, "elasticsearch", false, 0)
|
_, err := shuffle.RunInit(*shuffle.GetDatastore(), *shuffle.GetStorage(), "", "worker", true, "elasticsearch", false, 0)
|
||||||
@@ -3729,7 +3729,7 @@ func main() {
|
|||||||
swarmConfig := os.Getenv("SHUFFLE_SWARM_CONFIG")
|
swarmConfig := os.Getenv("SHUFFLE_SWARM_CONFIG")
|
||||||
log.Printf("[INFO] Running with timezone %s and swarm config %#v", timezone, swarmConfig)
|
log.Printf("[INFO] Running with timezone %s and swarm config %#v", timezone, swarmConfig)
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if swarmConfig == "run" || swarmConfig == "swarm" {
|
if swarmConfig == "run" || swarmConfig == "swarm" {
|
||||||
// Forcing download just in case on the first iteration.
|
// Forcing download just in case on the first iteration.
|
||||||
log.Printf("[INFO] Running in swarm mode - forcing download of apps")
|
log.Printf("[INFO] Running in swarm mode - forcing download of apps")
|
||||||
@@ -3744,7 +3744,7 @@ func main() {
|
|||||||
log.Printf("[ERROR] Stopped listener %#v - exiting.", listener)
|
log.Printf("[ERROR] Stopped listener %#v - exiting.", listener)
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
}
|
}
|
||||||
/*** ***/
|
/*** ENDREMOVE ***/
|
||||||
|
|
||||||
authorization := ""
|
authorization := ""
|
||||||
executionId := ""
|
executionId := ""
|
||||||
@@ -4097,14 +4097,13 @@ func runWebserver(listener net.Listener) {
|
|||||||
// What would be require to run a workflow otherwise?
|
// What would be require to run a workflow otherwise?
|
||||||
// Maybe directly /workflow/run
|
// Maybe directly /workflow/run
|
||||||
|
|
||||||
/*** ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
log.Printf("[DEBUG] Running webserver config for SWARM and K8s")
|
log.Printf("[DEBUG] Running webserver config for SWARM and K8s")
|
||||||
}
|
}
|
||||||
|
/*** ENDREMOVE ***/
|
||||||
/*** ***/
|
// var dockercli *dockerclient.Client
|
||||||
var dockercli *dockerclient.Client
|
// ctx := context.Background()
|
||||||
defer dockercli.Close()
|
|
||||||
scaleReplicas := os.Getenv("SHUFFLE_APP_REPLICAS")
|
scaleReplicas := os.Getenv("SHUFFLE_APP_REPLICAS")
|
||||||
if len(scaleReplicas) > 0 {
|
if len(scaleReplicas) > 0 {
|
||||||
tmpInt, err := strconv.Atoi(scaleReplicas)
|
tmpInt, err := strconv.Atoi(scaleReplicas)
|
||||||
@@ -4130,13 +4129,9 @@ func runWebserver(listener net.Listener) {
|
|||||||
log.Printf("[DEBUG] SHUFFLE_APP_EXECUTIONS_PER_MINUTE set to value %s. Trying to overwrite default (%d)", os.Getenv("SHUFFLE_APP_EXECUTIONS_PER_MINUTE"), maxExecutionsPerMinute)
|
log.Printf("[DEBUG] SHUFFLE_APP_EXECUTIONS_PER_MINUTE set to value %s. Trying to overwrite default (%d)", os.Getenv("SHUFFLE_APP_EXECUTIONS_PER_MINUTE"), maxExecutionsPerMinute)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
ctx := context.Background()
|
|
||||||
if strings.ToLower(os.Getenv("SHUFFLE_SWARM_CONFIG")) == "run" || strings.ToLower(os.Getenv("SHUFFLE_APP_REPLICAS")) == "" {
|
if strings.ToLower(os.Getenv("SHUFFLE_SWARM_CONFIG")) == "run" || strings.ToLower(os.Getenv("SHUFFLE_APP_REPLICAS")) == "" {
|
||||||
go AutoScaleApps(ctx, dockercli, maxExecutionsPerMinute)
|
// go AutoScaleApps(ctx, dockercli, maxExecutionsPerMinute)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
if strings.ToLower(os.Getenv("SHUFFLE_DEBUG_MEMORY")) == "true" {
|
if strings.ToLower(os.Getenv("SHUFFLE_DEBUG_MEMORY")) == "true" {
|
||||||
r.HandleFunc("/debug/pprof/", pprof.Index)
|
r.HandleFunc("/debug/pprof/", pprof.Index)
|
||||||
r.HandleFunc("/debug/pprof/heap", pprof.Handler("heap").ServeHTTP)
|
r.HandleFunc("/debug/pprof/heap", pprof.Handler("heap").ServeHTTP)
|
||||||
@@ -4182,14 +4177,12 @@ func AutoScaleApps(ctx context.Context, client *dockerclient.Client, maxExecutio
|
|||||||
|
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
count := window.CountEvents(time.Now())
|
count := window.CountEvents(time.Now())
|
||||||
|
j := numberOfApps(ctx, client)
|
||||||
appNumber := numberOfApps(ctx, client)
|
|
||||||
workers := numberOfWorkers(ctx, client)
|
workers := numberOfWorkers(ctx, client)
|
||||||
|
|
||||||
execPerMin := maxExecutionsPerMinute / workers
|
execPerMin := maxExecutionsPerMinute / workers
|
||||||
if count >= execPerMin {
|
if count >= execPerMin {
|
||||||
log.Printf("[DEBUG] Too many executions per minute (%d). Scaling down to %d", count, execPerMin)
|
log.Printf("[DEBUG] Too many executions per minute (%d). Scaling down to %d", count, execPerMin)
|
||||||
scaleApps(ctx, client, uint64(appNumber+1))
|
scaleApps(ctx, client, uint64(j+1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user