Compare commits
306 Commits
v2.4.0
...
v2.9.0-RC1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
975b715a7c | ||
|
|
cf17f03ae0 | ||
|
|
64f3ee797e | ||
|
|
e287705e88 | ||
|
|
9583b2bae0 | ||
|
|
2698993a6d | ||
|
|
a14b595e8c | ||
|
|
d7957b85ae | ||
|
|
227a51423d | ||
|
|
ea0e7340cc | ||
|
|
999680e94b | ||
|
|
566dbbb157 | ||
|
|
75d995d54e | ||
|
|
908faa491b | ||
|
|
7a254e343e | ||
|
|
016ac336b9 | ||
|
|
1cfd3a10ad | ||
|
|
1838029d22 | ||
|
|
7767043a5a | ||
|
|
b1cfa6db19 | ||
|
|
623d5a5546 | ||
|
|
8c676eb965 | ||
|
|
1e4ccce36c | ||
|
|
1808206e74 | ||
|
|
0fbc2b92aa | ||
|
|
42d274e988 | ||
|
|
ec64680a66 | ||
|
|
d006b89efd | ||
|
|
48654c382d | ||
|
|
8d23168a87 | ||
|
|
e27baaec9d | ||
|
|
31a37ae506 | ||
|
|
6360f90102 | ||
|
|
b829003711 | ||
|
|
fae773b25a | ||
|
|
0e8df4441d | ||
|
|
35e7e26d67 | ||
|
|
14c88280f5 | ||
|
|
aaab9d3bc5 | ||
|
|
02095595c6 | ||
|
|
9a80664ce2 | ||
|
|
b69e7e4ddf | ||
|
|
db642782b0 | ||
|
|
33dedbbfa3 | ||
|
|
a8f53de511 | ||
|
|
3b7dad989f | ||
|
|
4d62c5298a | ||
|
|
538c6b5233 | ||
|
|
969a14802b | ||
|
|
5c7f683d16 | ||
|
|
c7874e5e40 | ||
|
|
628e4fa873 | ||
|
|
8e01abbeb6 | ||
|
|
89ee99f98d | ||
|
|
21452d091f | ||
|
|
d21f55b476 | ||
|
|
d01453ea1d | ||
|
|
09e3327e94 | ||
|
|
00deeb9fdd | ||
|
|
0aed1ba04f | ||
|
|
526947e3a1 | ||
|
|
b52308df80 | ||
|
|
bdb9e02df0 | ||
|
|
6273020127 | ||
|
|
4d1a464954 | ||
|
|
9711ab6c5f | ||
|
|
95963eb0be | ||
|
|
0596edb0a1 | ||
|
|
7ac82d4ad9 | ||
|
|
74a9ad955b | ||
|
|
c23cce672c | ||
|
|
d39b4b3624 | ||
|
|
2c3ebeec09 | ||
|
|
86f2ffa61f | ||
|
|
017781ff35 | ||
|
|
7d72ad0f37 | ||
|
|
152033f98a | ||
|
|
c21bf5b87d | ||
|
|
fa60d40171 | ||
|
|
d80d5557c8 | ||
|
|
6c7ac8d7f4 | ||
|
|
d72867da35 | ||
|
|
14347b73f2 | ||
|
|
11e2bf4cbb | ||
|
|
b2553d35fd | ||
|
|
58f8a02557 | ||
|
|
34450144ba | ||
|
|
f9e08d53af | ||
|
|
006e402d9f | ||
|
|
8132012534 | ||
|
|
3e8f02eea4 | ||
|
|
7312980453 | ||
|
|
8c20d41d89 | ||
|
|
d50d53ac1f | ||
|
|
b0d7ab2e81 | ||
|
|
91223b7518 | ||
|
|
616e4b6e0c | ||
|
|
5170ea81e7 | ||
|
|
53a8cd8ee4 | ||
|
|
2229e8cb7d | ||
|
|
9ce1041b0e | ||
|
|
187065098b | ||
|
|
467bdf0045 | ||
|
|
9462b5b461 | ||
|
|
da7f29a9e0 | ||
|
|
d06bfd91ff | ||
|
|
b9bba10697 | ||
|
|
4581de92ad | ||
|
|
72c520cca7 | ||
|
|
835ee2a046 | ||
|
|
d03dee8fda | ||
|
|
6e89598a51 | ||
|
|
0a2aa6f734 | ||
|
|
2e7836eec3 | ||
|
|
31bdda8bf8 | ||
|
|
2fc93fa819 | ||
|
|
3c5a939b16 | ||
|
|
0f40c4cd49 | ||
|
|
7ad184cb48 | ||
|
|
41a7d5d0a8 | ||
|
|
78c48e004c | ||
|
|
7106d61881 | ||
|
|
8ead4c4708 | ||
|
|
52ca7d3503 | ||
|
|
7d504da0a8 | ||
|
|
c6dee2252b | ||
|
|
680c4a9ec4 | ||
|
|
3887d57fa4 | ||
|
|
d733daed9d | ||
|
|
de8651ab52 | ||
|
|
0ce641d10b | ||
|
|
316224b424 | ||
|
|
cf9bbce284 | ||
|
|
6eae6c046e | ||
|
|
837a430228 | ||
|
|
71431f8fb5 | ||
|
|
0c7cd1f299 | ||
|
|
674682e919 | ||
|
|
a5ca8115af | ||
|
|
d4338fce42 | ||
|
|
14e8135f81 | ||
|
|
e925f07505 | ||
|
|
b792b51bd0 | ||
|
|
fb64813b2a | ||
|
|
b16e0e33ab | ||
|
|
818921e4a2 | ||
|
|
6c437459ca | ||
|
|
b276901874 | ||
|
|
85b92f46f5 | ||
|
|
237b8b5ede | ||
|
|
438d008c34 | ||
|
|
53a3de1ebc | ||
|
|
2d35747e75 | ||
|
|
71feebea6d | ||
|
|
c8c75e7a70 | ||
|
|
7b2263e9a5 | ||
|
|
9cd216bbba | ||
|
|
e032ff4485 | ||
|
|
fbe9ca5dd9 | ||
|
|
4533bb6dd7 | ||
|
|
3320c03603 | ||
|
|
c3574d96d7 | ||
|
|
ebd2419634 | ||
|
|
133c256543 | ||
|
|
98a2a72f33 | ||
|
|
bc12b598ce | ||
|
|
a34f679c43 | ||
|
|
f008fd082e | ||
|
|
d2fd895582 | ||
|
|
746a812ae8 | ||
|
|
b67c69b88b | ||
|
|
f6ee20730a | ||
|
|
2829a96c84 | ||
|
|
37e1a92a89 | ||
|
|
81c4717472 | ||
|
|
94aac686c9 | ||
|
|
b75848515b | ||
|
|
a26cf9a3ff | ||
|
|
a7e4f728d2 | ||
|
|
921d234972 | ||
|
|
6bec9f977f | ||
|
|
6eaa9f8af1 | ||
|
|
5ef189b445 | ||
|
|
9f8283892e | ||
|
|
6ba2dc9601 | ||
|
|
e23512c860 | ||
|
|
32b6fe1625 | ||
|
|
8663b6d108 | ||
|
|
7794aa4c99 | ||
|
|
ba90ea59f4 | ||
|
|
aadb4c44a1 | ||
|
|
467ad39873 | ||
|
|
0a92b2db48 | ||
|
|
60a8f1ea61 | ||
|
|
1063061b47 | ||
|
|
54186575e0 | ||
|
|
114005d572 | ||
|
|
cde59a5ab1 | ||
|
|
e6bb26ce12 | ||
|
|
0cde953d58 | ||
|
|
ce7a804a70 | ||
|
|
67716aedde | ||
|
|
54a98cd6e5 | ||
|
|
31a901bea9 | ||
|
|
f0fdc90226 | ||
|
|
e14f892bc6 | ||
|
|
39158b0d1e | ||
|
|
acc264534e | ||
|
|
48dcb4acbf | ||
|
|
1c40f9eb4c | ||
|
|
9e418eb423 | ||
|
|
e4ff3a87a7 | ||
|
|
e82551c97f | ||
|
|
d877a4aecf | ||
|
|
5c50a40bdb | ||
|
|
9caf0f375c | ||
|
|
1ed8285452 | ||
|
|
16170e613c | ||
|
|
b3fb45dd36 | ||
|
|
54f5912da6 | ||
|
|
8542ded488 | ||
|
|
e6561faf8c | ||
|
|
f291b7b0fc | ||
|
|
d9ea2abf1a | ||
|
|
60a072809b | ||
|
|
9828d6457d | ||
|
|
d6f390d7d4 | ||
|
|
6ddafc8de0 | ||
|
|
ed5c83cf66 | ||
|
|
bf227b5e6f | ||
|
|
8bc1350e2e | ||
|
|
3aa0dd2f51 | ||
|
|
6c1f1e1db7 | ||
|
|
0c615fcb3b | ||
|
|
3ca900af6c | ||
|
|
1481626b1b | ||
|
|
a0ba5aeca4 | ||
|
|
f48a922b4c | ||
|
|
2418273191 | ||
|
|
09a10d7838 | ||
|
|
40ed1dd612 | ||
|
|
2aa38f1117 | ||
|
|
5d81ad9830 | ||
|
|
dffb45e233 | ||
|
|
5606c7b29a | ||
|
|
9d5b4f63d3 | ||
|
|
2c353023ab | ||
|
|
6992cdbaa4 | ||
|
|
9576079bfa | ||
|
|
1e08ccaae3 | ||
|
|
80e07eb53a | ||
|
|
54b7a27e65 | ||
|
|
5dc6100e8e | ||
|
|
a5c1a7122d | ||
|
|
61442462c7 | ||
|
|
917c31bef4 | ||
|
|
989439587f | ||
|
|
e74130733e | ||
|
|
2cce9a4f4c | ||
|
|
b721dfeb71 | ||
|
|
645b9b2c37 | ||
|
|
b419ebfe5d | ||
|
|
96d40a2946 | ||
|
|
e9b40573c7 | ||
|
|
ad316dfeac | ||
|
|
62cbaf3c04 | ||
|
|
cdb7eb3da9 | ||
|
|
671e0bbf71 | ||
|
|
50704b7b6a | ||
|
|
c198d1f593 | ||
|
|
c91cd2eecf | ||
|
|
31e47f4a04 | ||
|
|
470a9c4afa | ||
|
|
98692be3ba | ||
|
|
5c5077d7ec | ||
|
|
c13cae9ab3 | ||
|
|
74de687b90 | ||
|
|
ed3aca7d0c | ||
|
|
c9467f31c8 | ||
|
|
ad08632809 | ||
|
|
bea47b2640 | ||
|
|
242078ec15 | ||
|
|
5ca140df46 | ||
|
|
1259212cb2 | ||
|
|
299c43e10d | ||
|
|
969450cad3 | ||
|
|
3da330b637 | ||
|
|
86bd64e887 | ||
|
|
e02f939cb8 | ||
|
|
4bde6e2d1f | ||
|
|
ee69783a66 | ||
|
|
cddb0e94fa | ||
|
|
b1277ff2ac | ||
|
|
262c1fe1e2 | ||
|
|
2d2603ff27 | ||
|
|
d349e43523 | ||
|
|
ebf2d7d5c6 | ||
|
|
411c618be1 | ||
|
|
6151dcb8ff | ||
|
|
3564abfa29 | ||
|
|
955becdb46 | ||
|
|
daba3a3f28 | ||
|
|
33b8d1a1f5 | ||
|
|
5e35c23883 | ||
|
|
601c369f2d | ||
|
|
d48925f9ba |
1
.env
Normal file
@@ -0,0 +1 @@
|
||||
VITE_UCENTRALSEC_URL="https://ucentral.dpaas.arilia.com:16001"
|
||||
@@ -1,4 +1,10 @@
|
||||
/src/assets
|
||||
/build
|
||||
/node_modules
|
||||
/dist
|
||||
/icons
|
||||
helm
|
||||
docker-entrypoint.d
|
||||
.dockerignore
|
||||
DockerFile
|
||||
.github
|
||||
|
||||
94
.eslintrc
@@ -1,22 +1,80 @@
|
||||
{
|
||||
"extends": ["airbnb", "prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"jest": true
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module",
|
||||
"allowImportExportEverywhere": false,
|
||||
"codeFrame": false,
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"ignorePatterns": ["build/", "dist/"],
|
||||
"extends": [
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"airbnb",
|
||||
"airbnb-typescript",
|
||||
"prettier",
|
||||
"plugin:import/errors",
|
||||
"plugin:import/warnings",
|
||||
"plugin:import/typescript"
|
||||
],
|
||||
"plugins": ["import", "react", "@typescript-eslint", "prettier"],
|
||||
"rules": {
|
||||
"max-len": ["error", {"code": 150}],
|
||||
"prefer-promise-reject-errors": ["off"],
|
||||
"react/jsx-filename-extension": ["off"],
|
||||
"react/prop-types": ["warn"],
|
||||
"no-return-assign": ["off"],
|
||||
"react/jsx-props-no-spreading": ["off"],
|
||||
"react/destructuring-assignment": ["off"],
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"ignorePackages",
|
||||
{
|
||||
"js": "never",
|
||||
"jsx": "never",
|
||||
"ts": "never",
|
||||
"tsx": "never"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"error",
|
||||
{
|
||||
"selector": "function",
|
||||
"format": ["PascalCase", "camelCase"],
|
||||
"leadingUnderscore": "allowSingleOrDouble"
|
||||
}
|
||||
],
|
||||
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"],
|
||||
"react/jsx-one-expression-per-line": "off",
|
||||
"react/jsx-wrap-multilines": "off",
|
||||
"react/jsx-curly-newline": "off"
|
||||
"react/function-component-definition": [2, { "namedComponents": "arrow-function" }],
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"alphabetize": {
|
||||
"order": "asc",
|
||||
"caseInsensitive": true
|
||||
},
|
||||
"newlines-between": "never",
|
||||
"groups": ["builtin", "external", "parent", "sibling", "index"],
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "react",
|
||||
"group": "external",
|
||||
"position": "before"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": ["builtin"]
|
||||
}
|
||||
],
|
||||
"max-len": ["error", { "code": 150 }],
|
||||
"@typescript-eslint/ban-ts-comment": ["off"],
|
||||
"import/prefer-default-export": ["off"],
|
||||
"react/prop-types": ["warn"],
|
||||
"react/require-default-props": "off",
|
||||
"react/jsx-props-no-spreading": ["off"],
|
||||
"react/jsx-curly-newline": "off",
|
||||
"no-underscore-dangle": "off"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
@@ -24,11 +82,5 @@
|
||||
"paths": ["src"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"allowImportExportEverywhere": false,
|
||||
"codeFrame": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
84
.github/workflows/ci.yml
vendored
@@ -12,6 +12,7 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- 'release/*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -24,45 +25,48 @@ jobs:
|
||||
DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
DOCKER_REGISTRY_USERNAME: ucentral
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build Docker image
|
||||
run: docker build -t owgw-ui:${{ github.sha }} .
|
||||
|
||||
- name: Tag Docker image
|
||||
run: |
|
||||
TAGS="${{ github.sha }}"
|
||||
|
||||
if [[ ${GITHUB_REF} == "refs/heads/"* ]]
|
||||
then
|
||||
CURRENT_TAG=$(echo ${GITHUB_REF#refs/heads/} | tr '/' '-')
|
||||
TAGS="$TAGS $CURRENT_TAG"
|
||||
else
|
||||
if [[ ${GITHUB_REF} == "refs/tags/"* ]]
|
||||
then
|
||||
CURRENT_TAG=$(echo ${GITHUB_REF#refs/tags/} | tr '/' '-')
|
||||
TAGS="$TAGS $CURRENT_TAG"
|
||||
else # PR build
|
||||
CURRENT_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||
TAGS="$TAGS $CURRENT_TAG"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Result tags: $TAGS"
|
||||
|
||||
for tag in $TAGS; do
|
||||
docker tag owgw-ui:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/owgw-ui:$tag
|
||||
done
|
||||
|
||||
- name: Log into Docker registry
|
||||
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
|
||||
uses: docker/login-action@v1
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY_URL }}
|
||||
username: ${{ env.DOCKER_REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
- name: Push Docker images
|
||||
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/owgw-ui | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {}
|
||||
- name: Build and push Docker image
|
||||
uses: ./github/composite-actions/docker-image-build
|
||||
with:
|
||||
image_name: owgw-ui
|
||||
registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
registry_user: ucentral
|
||||
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Notify on failure via Slack
|
||||
if: failure() && github.ref == 'refs/heads/main'
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
env:
|
||||
SLACK_USERNAME: GitHub Actions failure notifier
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_COLOR: "${{ job.status }}"
|
||||
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
|
||||
SLACK_TITLE: Docker build failed for OWGW-UI service
|
||||
|
||||
trigger-deploy-to-dev:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
needs:
|
||||
- docker
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
- name: Trigger deployment of the latest version to dev instance and wait for result
|
||||
uses: ./github/composite-actions/trigger-workflow-and-wait
|
||||
with:
|
||||
owner: Telecominfraproject
|
||||
repo: wlan-testing
|
||||
workflow: ucentralgw-dev-deployment.yaml
|
||||
token: ${{ secrets.WLAN_TESTING_PAT }}
|
||||
ref: master
|
||||
inputs: '{"force_latest": "true"}'
|
||||
|
||||
9
.github/workflows/cleanup.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- 'release/*'
|
||||
types: [ closed ]
|
||||
|
||||
defaults:
|
||||
@@ -16,4 +17,10 @@ jobs:
|
||||
steps:
|
||||
- run: |
|
||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owgw-ui/$PR_BRANCH_TAG"
|
||||
|
||||
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
|
||||
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
|
||||
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owgw-ui/$PR_BRANCH_TAG"
|
||||
else
|
||||
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
|
||||
fi
|
||||
|
||||
24
.github/workflows/enforce-jira-issue-key.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Ensure Jira issue is linked
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
branches:
|
||||
- 'release/*'
|
||||
|
||||
jobs:
|
||||
check_for_issue_key:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
- name: Run JIRA check
|
||||
uses: ./github/composite-actions/enforce-jira-issue-key
|
||||
with:
|
||||
jira_base_url: ${{ secrets.TIP_JIRA_URL }}
|
||||
jira_user_email: ${{ secrets.TIP_JIRA_USER_EMAIL }}
|
||||
jira_api_token: ${{ secrets.TIP_JIRA_API_TOKEN }}
|
||||
46
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Release chart package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
helm-package:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
HELM_REPO_USERNAME: ucentral
|
||||
steps:
|
||||
- name: Checkout uCentral assembly chart repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: wlan-cloud-ucentralgw-ui
|
||||
|
||||
- name: Build package
|
||||
working-directory: wlan-cloud-ucentralgw-ui/helm
|
||||
run: |
|
||||
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
helm repo update
|
||||
helm dependency update
|
||||
mkdir dist
|
||||
helm package . -d dist
|
||||
|
||||
- name: Generate GitHub release body
|
||||
working-directory: wlan-cloud-ucentralgw-ui/helm
|
||||
run: |
|
||||
pip3 install yq -q
|
||||
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owgw-ui:$GITHUB_REF_NAME" > release.txt
|
||||
echo "Helm charted may be attached to this release" >> release.txt
|
||||
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
|
||||
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
body_path: wlan-cloud-ucentralgw-ui/helm/release.txt
|
||||
files: wlan-cloud-ucentralgw-ui/helm/dist/*
|
||||
5
.gitignore
vendored
@@ -1,9 +1,8 @@
|
||||
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
/dev-dist
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
@@ -19,5 +18,3 @@
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/src/assets
|
||||
build
|
||||
dist
|
||||
node_modules
|
||||
.github
|
||||
|
||||
10
.prettierrc
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
"printWidth": 120,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
}
|
||||
12
Dockerfile
@@ -1,6 +1,8 @@
|
||||
FROM node:14-alpine3.11 AS build
|
||||
FROM node:18.7.0-alpine3.15 AS build
|
||||
|
||||
COPY package.json package-lock.json /
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json /app/
|
||||
|
||||
RUN npm install
|
||||
|
||||
@@ -8,8 +10,8 @@ COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.20.1-alpine AS runtime
|
||||
FROM nginx:1.22.0-alpine AS runtime
|
||||
|
||||
COPY --from=build /build/ /usr/share/nginx/html/
|
||||
COPY --from=build /app/build/ /usr/share/nginx/html/
|
||||
|
||||
COPY --from=build docker-entrypoint.d/40-generate-config.sh /docker-entrypoint.d/40-generate-config.sh
|
||||
COPY --from=build /app/docker-entrypoint.d/40-generate-config.sh /docker-entrypoint.d/40-generate-config.sh
|
||||
|
||||
25
README.md
@@ -1,6 +1,7 @@
|
||||
# uCentralGW UI
|
||||
|
||||
## What is this?
|
||||
|
||||
The uCentralGW Client is a user interface that lets you monitor and manage devices connected to the [uCentral gateway](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw). To use the interface,
|
||||
you either need to run it on your machine for [development](#development) or build it for [production](#production).
|
||||
|
||||
@@ -9,40 +10,34 @@ NOTE: This UI will be evolving as micro services are added to the uCentral progr
|
||||
## Running the solution
|
||||
|
||||
### Development
|
||||
|
||||
You need to run these commands in the root folder of the project and also have npm installed on your machine.
|
||||
|
||||
```
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui
|
||||
cd wlan-cloud-ucentralgw-ui
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Run these commands if you want to run the solution on your machine while also doing development on the [uCentral UI Library](https://github.com/Telecominfraproject/wlan-cloud-ucentral-ui-libs).
|
||||
```
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentral-ui-libs
|
||||
cd wlan-cloud-ucentralgw-ui
|
||||
npm link ../wlan-cloud-ucentral-ui-libs // Add sudo at the start of this command if it fails because of permissions
|
||||
npm start
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Production
|
||||
|
||||
You need to run this in the root folder of the project and also have npm installed on your machine.
|
||||
|
||||
```
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui
|
||||
cd wlan-cloud-ucentralgw-ui
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Once the build is done, you can move the `build` folder on your server.
|
||||
|
||||
### Configuration
|
||||
You must change the `config.json` file in `public` directory to point to your uCentral Security Service URL (uCentralSec). You may also limit the ability for users to change the default uCentralSec. If you do not allow a uCentralSec change, the uCentralSec URL will not appear on the login screen.
|
||||
|
||||
You can control the uCentral Security Service URL (uCentralSec) by modifying the ENV variable "VITE_UCENTRALSEC_URL". There is an example .env file located at the root of this repository.
|
||||
Here are the current default values:
|
||||
|
||||
```
|
||||
{
|
||||
"DEFAULT_UCENTRALSEC_URL": "https://ucentral.dpaas.arilia.com:16001",
|
||||
"ALLOW_UCENTRALSEC_CHANGE": false
|
||||
}
|
||||
VITE_UCENTRALSEC_URL="https://ucentral.dpaas.arilia.com:16001"
|
||||
```
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
],
|
||||
"@babel/preset-react"
|
||||
],
|
||||
"env": {
|
||||
"production": {
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-react-inline-elements",
|
||||
"@babel/plugin-transform-react-constant-elements",
|
||||
[
|
||||
"transform-react-remove-prop-types",
|
||||
{
|
||||
"removeImport": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
// Source files
|
||||
src: path.resolve(__dirname, '../src'),
|
||||
|
||||
// Production build files
|
||||
build: path.resolve(__dirname, '../build'),
|
||||
|
||||
// Static files that get copied to build folder
|
||||
public: path.resolve(__dirname, '../public'),
|
||||
};
|
||||
@@ -1,79 +0,0 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable prefer-template */
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
const paths = require('./paths');
|
||||
|
||||
module.exports = {
|
||||
entry: [paths.src + '/index.js'],
|
||||
output: {
|
||||
path: paths.build,
|
||||
filename: '[name].bundle.js',
|
||||
publicPath: '/',
|
||||
},
|
||||
resolve: {
|
||||
modules: [path.resolve('./node_modules'), path.resolve('./src')],
|
||||
preferRelative: true,
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.VERSION': JSON.stringify(process.env.npm_package_version),
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'styles/[name].[contenthash].css',
|
||||
chunkFilename: '[id].[contenthash].css',
|
||||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: paths.src + '/assets',
|
||||
to: 'assets',
|
||||
globOptions: {
|
||||
ignore: ['*.DS_Store'],
|
||||
},
|
||||
},
|
||||
{
|
||||
from: paths.public + '/locales',
|
||||
to: 'locales',
|
||||
globOptions: {
|
||||
ignore: ['*.DS_Store'],
|
||||
},
|
||||
},
|
||||
{
|
||||
from: paths.public + '/config.json',
|
||||
to: 'config.json',
|
||||
},
|
||||
],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'uCentralGW',
|
||||
favicon: paths.public + '/favicon.ico',
|
||||
template: paths.public + '/index.html',
|
||||
filename: 'index.html',
|
||||
}),
|
||||
new CleanWebpackPlugin(),
|
||||
],
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: ['babel-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
use: ['@svgr/webpack'],
|
||||
},
|
||||
{ test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource' },
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable prefer-template */
|
||||
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
||||
const { merge } = require('webpack-merge');
|
||||
const path = require('path');
|
||||
const paths = require('./paths');
|
||||
const common = require('./webpack.common');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
|
||||
target: 'web',
|
||||
|
||||
devtool: 'inline-source-map',
|
||||
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
contentBase: paths.build,
|
||||
open: true,
|
||||
compress: false,
|
||||
hot: true,
|
||||
port: 3000,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.[js]sx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('babel-loader'),
|
||||
options: {
|
||||
plugins: [require.resolve('react-refresh/babel')],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
'node_modules',
|
||||
'src',
|
||||
path.resolve(__dirname, '../', 'node_modules', 'ucentral-libs', 'src'),
|
||||
],
|
||||
alias: {
|
||||
react: path.resolve(__dirname, '../', 'node_modules', 'react'),
|
||||
'react-router-dom': path.resolve('./node_modules/react-router-dom'),
|
||||
'ucentral-libs': path.resolve(__dirname, '../', 'node_modules', 'ucentral-libs', 'src'),
|
||||
graphlib: path.resolve(__dirname, '../', 'node_modules', 'graphlib'),
|
||||
},
|
||||
},
|
||||
plugins: [new ReactRefreshWebpackPlugin()],
|
||||
});
|
||||
@@ -1,86 +0,0 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable prefer-template */
|
||||
const { merge } = require('webpack-merge');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const CompressionPlugin = require('compression-webpack-plugin');
|
||||
const path = require('path');
|
||||
const paths = require('./paths');
|
||||
const common = require('./webpack.common');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
output: {
|
||||
path: paths.build,
|
||||
publicPath: '/',
|
||||
filename: 'js/[name].[contenthash].bundle.js',
|
||||
},
|
||||
plugins: [
|
||||
// new BundleAnalyzerPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'styles/[name].[contenthash].css',
|
||||
chunkFilename: '[contenthash].css',
|
||||
}),
|
||||
new CompressionPlugin({
|
||||
filename: '[path]/[name].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
|
||||
threshold: 10240,
|
||||
minRatio: 0.8,
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [],
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
'...',
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
warnings: false,
|
||||
compress: {
|
||||
comparisons: false,
|
||||
},
|
||||
parse: {},
|
||||
mangle: true,
|
||||
output: {
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
parallel: true,
|
||||
}),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
nodeEnv: 'production',
|
||||
sideEffects: true,
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
maxInitialRequests: 10,
|
||||
minSize: 0,
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name(module) {
|
||||
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
|
||||
return `npm.${packageName.replace('@', '')}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
modules: [],
|
||||
alias: {
|
||||
graphlib: path.resolve(__dirname, '../', 'node_modules', 'graphlib'),
|
||||
},
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
maxEntrypointSize: 512000,
|
||||
maxAssetSize: 512000,
|
||||
},
|
||||
});
|
||||
@@ -1,6 +1,32 @@
|
||||
#!/bin/ash
|
||||
# Check if variables are set
|
||||
export DEFAULT_OWSEC_URL="${DEFAULT_OWSEC_URL:-https://ucentral.dpaas.arilia.com:16001}"
|
||||
export ALLOW_OWSEC_CHANGE="${ALLOW_OWSEC_CHANGE:-false}"
|
||||
|
||||
echo '{"DEFAULT_UCENTRALSEC_URL": "'$DEFAULT_UCENTRALSEC_URL'","ALLOW_UCENTRALSEC_CHANGE": '$ALLOW_UCENTRALSEC_CHANGE'}' > /usr/share/nginx/html/config.json
|
||||
ENV_CONFIG_PATH=/usr/share/nginx/html/env-config.js
|
||||
|
||||
# Recreate config file
|
||||
rm -rf $ENV_CONFIG_PATH
|
||||
touch $ENV_CONFIG_PATH
|
||||
|
||||
# Add assignment
|
||||
echo "window._env_ = {" >> $ENV_CONFIG_PATH
|
||||
|
||||
# Read each line in .env file
|
||||
# Each line represents key=value pairs
|
||||
env | grep REACT_ | while read -r line || [[ -n "$line" ]];
|
||||
do
|
||||
echo $line
|
||||
# Split env variables by character `=`
|
||||
if printf '%s\n' "$line" | grep -q -e '='; then
|
||||
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
|
||||
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
|
||||
fi
|
||||
|
||||
# Read value of current variable if exists as Environment variable
|
||||
value=$(printf '%s\n' "${!varname}")
|
||||
# Otherwise use value from .env file
|
||||
[[ -z $value ]] && value=${varvalue}
|
||||
|
||||
# Append configuration property to JS file
|
||||
echo " $varname: \"$value\"," >> $ENV_CONFIG_PATH
|
||||
done
|
||||
|
||||
echo "}" >> $ENV_CONFIG_PATH
|
||||
|
||||
@@ -20,7 +20,7 @@ Currently this chart is not assembled in charts archives, so [helm-git](https://
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
$ helm install --name my-release git+https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui@helm?ref=main
|
||||
$ helm install --name my-release git+https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui@helm/owgwui-0.1.0.tgz?ref=main
|
||||
```
|
||||
|
||||
The command deploys the Web UI on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
|
||||
|
||||
@@ -30,3 +30,13 @@ Create chart name and version as used by the chart label.
|
||||
{{- define "owgwui.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "owgwui.ingress.apiVersion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
|
||||
{{- print "networking.k8s.io/v1" -}}
|
||||
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
|
||||
{{- print "networking.k8s.io/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -11,6 +11,7 @@ metadata:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "owgwui.name" . }}
|
||||
@@ -26,6 +27,12 @@ spec:
|
||||
{{- with .Values.services.owgwui.labels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
|
||||
containers:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{{- range $ingress, $ingressValue := .Values.ingresses }}
|
||||
{{- if $ingressValue.enabled }}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
apiVersion: {{ include "owgwui.ingress.apiVersion" $root }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "owgwui.fullname" $root }}-{{ $ingress }}
|
||||
@@ -36,9 +36,23 @@ spec:
|
||||
paths:
|
||||
{{- range $ingressValue.paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
|
||||
pathType: {{ .pathType | default "ImplementationSpecific" }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
|
||||
service:
|
||||
name: {{ include "owgwui.fullname" $root }}-{{ .serviceName }}
|
||||
port:
|
||||
{{- if kindIs "string" .servicePort }}
|
||||
name: {{ .servicePort }}
|
||||
{{- else }}
|
||||
number: {{ .servicePort }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
serviceName: {{ include "owgwui.fullname" $root }}-{{ .serviceName }}
|
||||
servicePort: {{ .servicePort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# System
|
||||
replicaCount: 1
|
||||
revisionHistoryLimit: 2
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
@@ -7,7 +8,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owgwui:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw-ui
|
||||
tag: main
|
||||
tag: v2.9.0-RC1
|
||||
pullPolicy: Always
|
||||
|
||||
services:
|
||||
@@ -48,6 +49,7 @@ ingresses:
|
||||
- chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
serviceName: owgwui
|
||||
servicePort: http
|
||||
|
||||
@@ -69,7 +71,8 @@ tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# Application
|
||||
public_env_variables:
|
||||
DEFAULT_UCENTRALSEC_URL: https://ucentral.dpaas.arilia.com:16001
|
||||
ALLOW_UCENTRALSEC_CHANGE: false
|
||||
REACT_APP_UCENTRALSEC_URL: https://ucentral.dpaas.arilia.com:16001
|
||||
|
||||
21
index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Controller</title>
|
||||
<meta name="description" content="OpenWiFi Controller App" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<script src="/env-config.js"></script>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"paths": {
|
||||
"*": ["*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
31794
package-lock.json
generated
173
package.json
@@ -1,99 +1,96 @@
|
||||
{
|
||||
"name": "ucentral-client",
|
||||
"version": "2.4.3",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
"@coreui/icons-react": "^1.1.0",
|
||||
"@coreui/react": "^3.4.6",
|
||||
"@coreui/react-chartjs": "^1.1.0",
|
||||
"apexcharts": "^3.27.1",
|
||||
"axios": "^0.21.1",
|
||||
"axios-retry": "^3.1.9",
|
||||
"dagre": "^0.8.5",
|
||||
"i18next": "^20.3.1",
|
||||
"i18next-browser-languagedetector": "^6.1.2",
|
||||
"i18next-http-backend": "^1.2.6",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^17.0.2",
|
||||
"react-apexcharts": "^1.3.9",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-flow-renderer": "^9.6.6",
|
||||
"react-i18next": "^11.11.0",
|
||||
"react-paginate": "^7.1.3",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-select": "^4.3.1",
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-widgets": "^5.1.1",
|
||||
"sass": "^1.35.1",
|
||||
"ucentral-libs": "^1.0.37",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
"version": "2.9.0(13)",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"main": "index.tsx",
|
||||
"scripts": {
|
||||
"start": "webpack serve --config config/webpack.dev.js",
|
||||
"build": "webpack --config config/webpack.prod.js",
|
||||
"format": "prettier --write 'src/**/*.js'",
|
||||
"eslint-fix": "eslint --fix 'src/**/*.js'"
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"format": "prettier --write \"src/**/*.js\"",
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
||||
"lint": "TIMING=1 eslint \"src/**/*.{ts,tsx,js,jsx}\" --fix",
|
||||
"clean": "rm -rf node_modules && rm -rf build"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx}": [
|
||||
"eslint",
|
||||
"prettier --write"
|
||||
]
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@chakra-ui/icons": "^2.0.11",
|
||||
"@chakra-ui/react": "^2.3.6",
|
||||
"@chakra-ui/theme-tools": "^2.0.12",
|
||||
"@chakra-ui/utils": "^2.0.11",
|
||||
"@emotion/react": "^11.10.4",
|
||||
"@emotion/styled": "^11.10.4",
|
||||
"@fontsource/inter": "^4.5.14",
|
||||
"@googlemaps/react-wrapper": "^1.1.35",
|
||||
"@googlemaps/typescript-guards": "^2.0.3",
|
||||
"@react-spring/web": "^9.5.5",
|
||||
"axios": "^1.1.3",
|
||||
"buffer": "^6.0.3",
|
||||
"chakra-react-select": "^4.3.0",
|
||||
"dagre": "^0.8.5",
|
||||
"formik": "^2.2.9",
|
||||
"fast-equals": "^4.0.3",
|
||||
"framer-motion": "^7.6.1",
|
||||
"i18next": "^22.0.0",
|
||||
"i18next-browser-languagedetector": "^6.1.8",
|
||||
"i18next-http-backend": "^1.4.4",
|
||||
"libphonenumber-js": "^1.10.14",
|
||||
"phosphor-react": "^1.4.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-app-polyfill": "^3.0.0",
|
||||
"react-chartjs-2": "^4.3.1",
|
||||
"chart.js": "^3.9.1",
|
||||
"react-country-flag": "^3.0.2",
|
||||
"react-csv": "^2.2.2",
|
||||
"react-datepicker": "^4.8.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"@textea/json-viewer": "^2.10.0",
|
||||
"react-fast-compare": "^3.2.0",
|
||||
"react-i18next": "^11.18.6",
|
||||
"react-masonry-css": "^1.0.16",
|
||||
"@tanstack/react-query": "^4.12.0",
|
||||
"react-router-dom": "^6.4.2",
|
||||
"react-table": "^7.8.0",
|
||||
"react-virtualized-auto-sizer": "^1.0.7",
|
||||
"react-window": "^1.8.8",
|
||||
"source-map-explorer": "^2.5.3",
|
||||
"vite": "^3.1.8",
|
||||
"typescript": "^4.8.4",
|
||||
"uuid": "^9.0.0",
|
||||
"yup": "^0.32.11",
|
||||
"zustand": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/plugin-transform-runtime": "^7.14.5",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"@babel/preset-react": "^7.14.5",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"autoprefixer": "^10.2.6",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"compression-webpack-plugin": "^8.0.1",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^5.2.6",
|
||||
"css-minimizer-webpack-plugin": "^2.0.0",
|
||||
"dotenv-webpack": "^6.0.4",
|
||||
"eslint": "^7.29.0",
|
||||
"eslint-config-airbnb": "^18.2.1",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"@types/google.maps": "^3.51.0",
|
||||
"@types/node": "^18.11.2",
|
||||
"@types/react": "^18.0.21",
|
||||
"@types/react-csv": "^1.1.3",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react-table": "^7.7.12",
|
||||
"@types/react-datepicker": "4.8.0",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
||||
"@types/react-window": "^1.8.5",
|
||||
"eslint": "8.25.0",
|
||||
"vite-tsconfig-paths": "^3.5.1",
|
||||
"lint-staged": "^13.0.3",
|
||||
"@vitejs/plugin-react": "^2.1.0",
|
||||
"vite-plugin-pwa": "^0.13.1",
|
||||
"prettier": "^2.7.1",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-airbnb-typescript-prettier": "^5.0.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
"husky": "^4.3.8",
|
||||
"lint-staged": "^11.0.0",
|
||||
"mini-css-extract-plugin": "^1.6.1",
|
||||
"node-sass": "^5.0.0",
|
||||
"path": "^0.12.7",
|
||||
"prettier": "^2.3.2",
|
||||
"react-refresh": "^0.9.0",
|
||||
"sass-loader": "^11.1.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"terser-webpack-plugin": "^5.1.4",
|
||||
"webpack": "^5.40.0",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-merge": "^5.8.0"
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.1",
|
||||
"eslint-plugin-no-inline-styles": "^1.0.5",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.31.10",
|
||||
"eslint-plugin-react-hooks": "^4.6.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
BIN
public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/android-chrome-384x384.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
9
public/browserconfig.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#414141</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"DEFAULT_UCENTRALSEC_URL": "https://ucentral.dpaas.arilia.com:16001",
|
||||
"ALLOW_UCENTRALSEC_CHANGE": false
|
||||
}
|
||||
BIN
public/devices/cig_wf160d.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
public/devices/cig_wf188.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/devices/cig_wf188n.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/devices/cig_wf194c.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
public/devices/cig_wf194c4.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
public/devices/cig_wf808.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
public/devices/cig_wf809.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
public/devices/edgecore_eap101.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
public/devices/edgecore_eap102.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
public/devices/edgecore_ecs4100-12ph.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
public/devices/edgecore_ecw5211.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
public/devices/edgecore_ecw5410.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
BIN
public/devices/edgecore_oap100.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
public/devices/edgecore_spw2ac1200-lan-poe.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/devices/edgecore_spw2ac1200.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/devices/edgecore_ssw2ac2600.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
public/devices/hfcl_ion4.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
public/devices/hfcl_ion4.yml.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
public/devices/indio_um-305ac.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/devices/linksys_e8450-ubi.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/devices/linksys_ea6350-v4.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
public/devices/linksys_ea6350.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
public/devices/linksys_ea8300.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
public/devices/tp-link_ec420-g1.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
public/devices/tplink_ec420.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
public/devices/tplink_ex227.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
public/devices/tplink_ex228.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
public/devices/tplink_ex447.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
public/devices/wallys_dr40x9.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/devices/wallys_dr6018.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/devices/wallys_dr6018_v4.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/devices/yuncore_ax840.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/devices/yuncore_fap640.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/devices/yuncore_fap650.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1021 B |
BIN
public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 15 KiB |
@@ -1,165 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 141.5 185.6" style="enable-background:new 0 0 141.5 185.6;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#414141;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#FED206;}
|
||||
.st3{fill:#EB6F53;}
|
||||
.st4{fill:#3BA9B6;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M120.7,183.9H21.5c-10.8,0-19.5-8.7-19.5-19.5V20.5c0-10.8,8.7-19.5,19.5-19.5h99.2
|
||||
c10.8,0,19.5,8.7,19.5,19.5v143.9C140.2,175.2,131.5,183.9,120.7,183.9z"/>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M46.3,166.2v-3.4h-1.2v-0.6h3.1v0.6H47v3.4H46.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M49,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H49z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M52.6,166.2v-4h0.7v3.4h1.8v0.6H52.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M55.7,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H55.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M59.1,164.2c0-1.2,0.9-2.1,2.1-2.1c0.8,0,1.3,0.4,1.6,0.9l-0.6,0.3c-0.2-0.3-0.6-0.6-1-0.6
|
||||
c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.4,0,0.8-0.3,1-0.6l0.6,0.3c-0.3,0.5-0.8,0.9-1.6,0.9
|
||||
C60,166.3,59.1,165.5,59.1,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M63.2,164.2c0-1.2,0.8-2.1,2-2.1c1.2,0,2,0.9,2,2.1c0,1.2-0.8,2.1-2,2.1C64,166.3,63.2,165.4,63.2,164.2z
|
||||
M66.5,164.2c0-0.8-0.5-1.4-1.3-1.4c-0.8,0-1.3,0.6-1.3,1.4c0,0.8,0.5,1.4,1.3,1.4C66,165.7,66.5,165,66.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M71.3,166.2v-3.1l-1.2,3.1h-0.3l-1.2-3.1v3.1h-0.7v-4h1l1.1,2.7l1.1-2.7h1v4H71.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M75.7,166.2v-4h0.7v4H75.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M80.4,166.2l-2.1-2.8v2.8h-0.7v-4h0.7l2,2.8v-2.8h0.7v4H80.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M82.3,166.2v-4H85v0.6h-2v1h2v0.6h-2v1.7H82.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M87.9,166.2l-0.9-1.5h-0.7v1.5h-0.7v-4h1.7c0.8,0,1.3,0.5,1.3,1.2c0,0.7-0.5,1.1-0.9,1.2l1,1.6H87.9z
|
||||
M88,163.5c0-0.4-0.3-0.6-0.7-0.6h-1v1.3h1C87.7,164.1,88,163.9,88,163.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M92.4,166.2l-0.3-0.8h-1.8l-0.3,0.8h-0.8l1.6-4h0.9l1.6,4H92.4z M91.2,162.9l-0.7,1.9h1.4L91.2,162.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M95.8,166.2v-4h1.5c0.8,0,1.2,0.5,1.2,1.2c0,0.6-0.4,1.2-1.2,1.2h-1.2v1.7H95.8z M98.2,163.4
|
||||
c0-0.5-0.3-0.9-0.9-0.9h-1.1v1.7h1.1C97.8,164.3,98.2,163.9,98.2,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M101.5,166.2l-1.1-1.6h-0.9v1.6h-0.3v-4h1.5c0.7,0,1.2,0.4,1.2,1.2c0,0.7-0.5,1.1-1.1,1.1l1.2,1.7H101.5z
|
||||
M101.6,163.4c0-0.5-0.4-0.9-0.9-0.9h-1.1v1.7h1.1C101.2,164.3,101.6,163.9,101.6,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M102.8,164.2c0-1.2,0.8-2.1,1.9-2.1c1.2,0,1.9,0.9,1.9,2.1c0,1.2-0.8,2.1-1.9,2.1
|
||||
C103.6,166.3,102.8,165.4,102.8,164.2z M106.3,164.2c0-1-0.6-1.7-1.6-1.7c-1,0-1.6,0.7-1.6,1.7c0,1,0.6,1.7,1.6,1.7
|
||||
C105.7,166,106.3,165.2,106.3,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M106.9,165.8l0.2-0.3c0.2,0.2,0.4,0.4,0.8,0.4c0.5,0,0.9-0.4,0.9-0.9v-2.8h0.3v2.8c0,0.8-0.5,1.2-1.2,1.2
|
||||
C107.5,166.3,107.2,166.1,106.9,165.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M110.4,166.2v-4h2.5v0.3h-2.2v1.5h2.1v0.3h-2.1v1.6h2.2v0.3H110.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M113.5,164.2c0-1.2,0.9-2.1,2-2.1c0.6,0,1.1,0.3,1.5,0.7l-0.3,0.2c-0.3-0.3-0.7-0.6-1.2-0.6
|
||||
c-0.9,0-1.7,0.7-1.7,1.7c0,1,0.7,1.7,1.7,1.7c0.5,0,0.9-0.2,1.2-0.6l0.3,0.2c-0.4,0.4-0.8,0.7-1.5,0.7
|
||||
C114.4,166.3,113.5,165.5,113.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M118.7,166.2v-3.7h-1.3v-0.3h2.9v0.3H119v3.7H118.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1" points="26.3,163.8 31.6,158.5 36.9,163.8 37.7,163.8 31.6,157.6 25.5,163.8 "/>
|
||||
<polygon class="st1" points="36.9,164.7 31.6,170 26.3,164.7 25.5,164.7 31.6,170.8 37.7,164.7 "/>
|
||||
<polygon class="st1" points="31,163.8 36.3,158.5 41.6,163.8 42.5,163.8 36.3,157.6 30.2,163.8 "/>
|
||||
<polygon class="st1" points="41.6,164.7 36.3,170 31,164.7 30.2,164.7 36.3,170.8 42.5,164.7 "/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M33.2,100.7c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3S37.8,100.7,33.2,100.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M33.2,35.2c40.7,0,73.8,33.1,73.8,73.8c0,0.7,0,1.4,0,2.1c0,1.7,0.6,3.3,1.7,4.6c1.2,1.2,2.8,1.9,4.5,2
|
||||
l0.2,0c3.5,0,6.3-2.7,6.4-6.2c0-0.8,0-1.7,0-2.5c0-47.7-38.8-86.6-86.6-86.6c-0.8,0-1.7,0-2.5,0c-1.7,0-3.3,0.8-4.5,2
|
||||
c-1.2,1.2-1.8,2.9-1.7,4.6c0.1,3.5,3,6.3,6.6,6.2C31.8,35.2,32.5,35.2,33.2,35.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M33.2,60.5c26.7,0,48.5,21.7,48.5,48.5c0,0.6,0,1.3,0,2c-0.1,1.7,0.5,3.3,1.7,4.6c1.2,1.3,2.7,2,4.4,2.1
|
||||
c1.7,0.1,3.3-0.5,4.6-1.7c1.2-1.2,2-2.7,2-4.4c0-0.9,0.1-1.8,0.1-2.6c0-33.8-27.5-61.2-61.2-61.2c-0.8,0-1.6,0-2.6,0.1
|
||||
c-1.7,0.1-3.3,0.8-4.4,2.1c-1.2,1.3-1.8,2.9-1.7,4.6s0.8,3.3,2.1,4.4c1.3,1.2,2.9,1.8,4.6,1.7C31.9,60.5,32.6,60.5,33.2,60.5z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st4" d="M33.2,86.7c12.3,0,22.3,10,22.3,22.3c0,0.5,0,1.1-0.1,1.8c-0.3,3.5,2.3,6.6,5.8,6.9
|
||||
c3.5,0.3,6.6-2.3,6.9-5.8c0.1-1,0.1-1.9,0.1-2.8c0-19.3-15.7-35.1-35.1-35.1c-0.9,0-1.8,0-2.8,0.1c-1.7,0.1-3.2,0.9-4.3,2.2
|
||||
c-1.1,1.3-1.6,2.9-1.5,4.6c0.1,1.7,0.9,3.2,2.2,4.3c1.3,1.1,2.9,1.6,4.6,1.5C32.1,86.7,32.7,86.7,33.2,86.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M35.8,130.4c1.1,0.6,2.1,1.5,2.7,2.6c0.7,1.1,1,2.3,1,3.7s-0.3,2.6-1,3.7c-0.7,1.1-1.6,2-2.7,2.6
|
||||
c-1.1,0.6-2.4,1-3.8,1s-2.7-0.3-3.8-1c-1.1-0.6-2.1-1.5-2.7-2.6c-0.7-1.1-1-2.3-1-3.7c0-1.3,0.3-2.6,1-3.7c0.7-1.1,1.6-2,2.7-2.6
|
||||
c1.1-0.6,2.4-0.9,3.8-0.9C33.4,129.5,34.7,129.8,35.8,130.4z M29.9,132.9c-0.7,0.4-1.2,0.9-1.6,1.6s-0.6,1.4-0.6,2.2
|
||||
c0,0.8,0.2,1.6,0.6,2.3c0.4,0.7,0.9,1.2,1.6,1.6c0.7,0.4,1.4,0.6,2.1,0.6c0.8,0,1.5-0.2,2.1-0.6c0.6-0.4,1.2-0.9,1.5-1.6
|
||||
c0.4-0.7,0.6-1.4,0.6-2.3c0-0.8-0.2-1.6-0.6-2.2s-0.9-1.2-1.5-1.6c-0.6-0.4-1.4-0.6-2.1-0.6C31.3,132.3,30.6,132.5,29.9,132.9z"/>
|
||||
<path class="st1" d="M50.6,133.6c0.8,0.5,1.4,1.1,1.8,2c0.4,0.8,0.6,1.8,0.6,2.9c0,1.1-0.2,2-0.6,2.8c-0.4,0.8-1,1.5-1.8,1.9
|
||||
c-0.8,0.5-1.6,0.7-2.6,0.7c-0.7,0-1.4-0.1-2-0.4s-1.1-0.7-1.5-1.2v5.4h-3.1V133h3.1v1.6c0.4-0.5,0.9-1,1.4-1.2s1.2-0.4,2-0.4
|
||||
C48.9,132.9,49.8,133.1,50.6,133.6z M49.1,140.5c0.5-0.6,0.7-1.3,0.7-2.2c0-0.9-0.2-1.6-0.7-2.1c-0.5-0.6-1.1-0.8-1.9-0.8
|
||||
s-1.4,0.3-1.9,0.8c-0.5,0.6-0.8,1.3-0.8,2.1c0,0.9,0.2,1.6,0.8,2.2s1.1,0.8,1.9,0.8S48.6,141,49.1,140.5z"/>
|
||||
<path class="st1" d="M63.4,134.4c0.9,1,1.4,2.4,1.4,4.2c0,0.3,0,0.6,0,0.7H57c0.2,0.7,0.5,1.2,1,1.6c0.5,0.4,1.1,0.6,1.8,0.6
|
||||
c0.5,0,1-0.1,1.5-0.3s0.9-0.5,1.3-0.9l1.6,1.6c-0.5,0.6-1.2,1.1-2,1.4c-0.8,0.3-1.6,0.5-2.6,0.5c-1.1,0-2.1-0.2-3-0.7
|
||||
s-1.5-1.1-2-1.9c-0.5-0.8-0.7-1.8-0.7-2.9c0-1.1,0.2-2.1,0.7-2.9s1.1-1.5,2-1.9c0.8-0.5,1.8-0.7,2.9-0.7
|
||||
C61.2,132.9,62.5,133.4,63.4,134.4z M61.8,137.5c0-0.7-0.3-1.3-0.7-1.7s-1-0.6-1.7-0.6c-0.7,0-1.2,0.2-1.7,0.6
|
||||
c-0.4,0.4-0.7,1-0.9,1.7H61.8z"/>
|
||||
<path class="st1" d="M76.2,134c0.7,0.7,1.1,1.7,1.1,3v6.8h-3.1v-5.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.5-0.6
|
||||
c-0.8,0-1.4,0.3-1.8,0.8c-0.4,0.5-0.7,1.2-0.7,2v5.3h-3.1V133h3.1v1.9c0.7-1.3,2-2,3.7-2C74.6,132.8,75.5,133.2,76.2,134z"/>
|
||||
<path class="st1" d="M96,129.7h3.3l-4.7,14h-3.3l-2.9-10.1l-3,10.1h-3.2l-4.7-14h3.4l3,10.7l3-10.7H90l3.1,10.7L96,129.7z"/>
|
||||
<path class="st1" d="M103.3,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C102.6,128.2,103,128.3,103.3,128.7z M100.6,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
<path class="st1" d="M106.5,129.7h10.1l0,2.6h-6.9v3.4h6.3v2.6h-6.3v5.3h-3.2V129.7z"/>
|
||||
<path class="st1" d="M120.9,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C120.1,128.2,120.5,128.3,120.9,128.7z M118.1,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<title>Gateway</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
public/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
38
public/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="744.000000pt" height="744.000000pt" viewBox="0 0 744.000000 744.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,744.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1827 7404 c-2 -2 -50 -6 -108 -8 -57 -3 -120 -10 -139 -15 -19 -6
|
||||
-56 -16 -82 -22 -27 -7 -48 -16 -48 -20 0 -4 -14 -10 -30 -14 -17 -4 -36 -12
|
||||
-43 -18 -7 -7 -28 -21 -46 -31 -115 -64 -247 -224 -304 -366 -59 -150 -55 65
|
||||
-56 -3180 0 -3270 -5 -3017 60 -3178 92 -232 303 -410 546 -463 32 -7 65 -14
|
||||
73 -16 22 -5 4127 -3 4180 2 77 7 279 77 300 104 3 3 25 19 50 35 56 37 135
|
||||
116 180 181 19 28 38 52 43 53 4 2 5 7 2 12 -3 4 2 13 10 20 8 7 15 21 15 31
|
||||
0 10 4 20 9 23 8 6 39 91 47 131 2 11 7 31 11 45 4 14 8 1364 9 3000 2 3142 3
|
||||
3032 -42 3165 -43 130 -131 255 -245 350 -33 28 -123 90 -127 87 -1 -1 -16 5
|
||||
-34 14 -35 18 -128 50 -173 59 -30 6 -187 18 -215 16 -57 -3 -122 -1 -129 4
|
||||
-5 3 -11 1 -13 -4 -1 -5 -23 -6 -48 -2 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -23 -4 -48 0 -25 4 -58 4 -75 1 -16 -3 -49 -3 -72 1
|
||||
-23 3 -44 2 -45 -2 -2 -4 -24 -4 -50 0 -27 5 -49 6 -51 5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
39
src/App.js
@@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import { HashRouter, Switch } from 'react-router-dom';
|
||||
import 'scss/style.scss';
|
||||
import Router from 'router';
|
||||
import { AuthProvider } from 'ucentral-libs';
|
||||
import { checkIfJson } from 'utils/helper';
|
||||
import axiosInstance from 'utils/axiosInstance';
|
||||
import { getItem } from 'utils/localStorageHelper';
|
||||
|
||||
const loading = (
|
||||
<div className="pt-3 text-center">
|
||||
<div className="sk-spinner sk-spinner-pulse" />
|
||||
</div>
|
||||
);
|
||||
|
||||
const App = () => {
|
||||
const storageToken = getItem('access_token');
|
||||
const apiEndpoints = checkIfJson(getItem('gateway_endpoints'))
|
||||
? JSON.parse(getItem('gateway_endpoints'))
|
||||
: {};
|
||||
|
||||
return (
|
||||
<AuthProvider
|
||||
axiosInstance={axiosInstance}
|
||||
token={storageToken ?? ''}
|
||||
apiEndpoints={apiEndpoints}
|
||||
>
|
||||
<HashRouter>
|
||||
<React.Suspense fallback={loading}>
|
||||
<Switch>
|
||||
<Router />
|
||||
</Switch>
|
||||
</React.Suspense>
|
||||
</HashRouter>
|
||||
</AuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
45
src/App.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React, { Suspense } from 'react';
|
||||
import { Spinner } from '@chakra-ui/react';
|
||||
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
|
||||
import { HashRouter } from 'react-router-dom';
|
||||
import { AuthProvider } from 'contexts/AuthProvider';
|
||||
import { ControllerSocketProvider } from 'contexts/ControllerSocketProvider';
|
||||
import { FirmwareSocketProvider } from 'contexts/FirmwareSocketProvider';
|
||||
import { ProvisioningSocketProvider } from 'contexts/ProvisioningSocketProvider';
|
||||
import { SecuritySocketProvider } from 'contexts/SecuritySocketProvider';
|
||||
import Router from 'router';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: 0,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const App = () => {
|
||||
const storageToken = localStorage.getItem('access_token') ?? sessionStorage.getItem('access_token');
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<HashRouter>
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<AuthProvider token={storageToken !== null ? storageToken : undefined}>
|
||||
<SecuritySocketProvider>
|
||||
<FirmwareSocketProvider>
|
||||
<ProvisioningSocketProvider>
|
||||
<ControllerSocketProvider>
|
||||
<Router />
|
||||
</ControllerSocketProvider>
|
||||
</ProvisioningSocketProvider>
|
||||
</FirmwareSocketProvider>
|
||||
</SecuritySocketProvider>
|
||||
</AuthProvider>
|
||||
</Suspense>
|
||||
</HashRouter>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
@@ -1,165 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 141.5 185.6" style="enable-background:new 0 0 141.5 185.6;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#414141;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#FED206;}
|
||||
.st3{fill:#EB6F53;}
|
||||
.st4{fill:#3BA9B6;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M120.7,183.9H21.5c-10.8,0-19.5-8.7-19.5-19.5V20.5c0-10.8,8.7-19.5,19.5-19.5h99.2
|
||||
c10.8,0,19.5,8.7,19.5,19.5v143.9C140.2,175.2,131.5,183.9,120.7,183.9z"/>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M46.3,166.2v-3.4h-1.2v-0.6h3.1v0.6H47v3.4H46.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M49,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H49z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M52.6,166.2v-4h0.7v3.4h1.8v0.6H52.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M55.7,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H55.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M59.1,164.2c0-1.2,0.9-2.1,2.1-2.1c0.8,0,1.3,0.4,1.6,0.9l-0.6,0.3c-0.2-0.3-0.6-0.6-1-0.6
|
||||
c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.4,0,0.8-0.3,1-0.6l0.6,0.3c-0.3,0.5-0.8,0.9-1.6,0.9
|
||||
C60,166.3,59.1,165.5,59.1,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M63.2,164.2c0-1.2,0.8-2.1,2-2.1c1.2,0,2,0.9,2,2.1c0,1.2-0.8,2.1-2,2.1C64,166.3,63.2,165.4,63.2,164.2z
|
||||
M66.5,164.2c0-0.8-0.5-1.4-1.3-1.4c-0.8,0-1.3,0.6-1.3,1.4c0,0.8,0.5,1.4,1.3,1.4C66,165.7,66.5,165,66.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M71.3,166.2v-3.1l-1.2,3.1h-0.3l-1.2-3.1v3.1h-0.7v-4h1l1.1,2.7l1.1-2.7h1v4H71.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M75.7,166.2v-4h0.7v4H75.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M80.4,166.2l-2.1-2.8v2.8h-0.7v-4h0.7l2,2.8v-2.8h0.7v4H80.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M82.3,166.2v-4H85v0.6h-2v1h2v0.6h-2v1.7H82.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M87.9,166.2l-0.9-1.5h-0.7v1.5h-0.7v-4h1.7c0.8,0,1.3,0.5,1.3,1.2c0,0.7-0.5,1.1-0.9,1.2l1,1.6H87.9z
|
||||
M88,163.5c0-0.4-0.3-0.6-0.7-0.6h-1v1.3h1C87.7,164.1,88,163.9,88,163.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M92.4,166.2l-0.3-0.8h-1.8l-0.3,0.8h-0.8l1.6-4h0.9l1.6,4H92.4z M91.2,162.9l-0.7,1.9h1.4L91.2,162.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M95.8,166.2v-4h1.5c0.8,0,1.2,0.5,1.2,1.2c0,0.6-0.4,1.2-1.2,1.2h-1.2v1.7H95.8z M98.2,163.4
|
||||
c0-0.5-0.3-0.9-0.9-0.9h-1.1v1.7h1.1C97.8,164.3,98.2,163.9,98.2,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M101.5,166.2l-1.1-1.6h-0.9v1.6h-0.3v-4h1.5c0.7,0,1.2,0.4,1.2,1.2c0,0.7-0.5,1.1-1.1,1.1l1.2,1.7H101.5z
|
||||
M101.6,163.4c0-0.5-0.4-0.9-0.9-0.9h-1.1v1.7h1.1C101.2,164.3,101.6,163.9,101.6,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M102.8,164.2c0-1.2,0.8-2.1,1.9-2.1c1.2,0,1.9,0.9,1.9,2.1c0,1.2-0.8,2.1-1.9,2.1
|
||||
C103.6,166.3,102.8,165.4,102.8,164.2z M106.3,164.2c0-1-0.6-1.7-1.6-1.7c-1,0-1.6,0.7-1.6,1.7c0,1,0.6,1.7,1.6,1.7
|
||||
C105.7,166,106.3,165.2,106.3,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M106.9,165.8l0.2-0.3c0.2,0.2,0.4,0.4,0.8,0.4c0.5,0,0.9-0.4,0.9-0.9v-2.8h0.3v2.8c0,0.8-0.5,1.2-1.2,1.2
|
||||
C107.5,166.3,107.2,166.1,106.9,165.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M110.4,166.2v-4h2.5v0.3h-2.2v1.5h2.1v0.3h-2.1v1.6h2.2v0.3H110.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M113.5,164.2c0-1.2,0.9-2.1,2-2.1c0.6,0,1.1,0.3,1.5,0.7l-0.3,0.2c-0.3-0.3-0.7-0.6-1.2-0.6
|
||||
c-0.9,0-1.7,0.7-1.7,1.7c0,1,0.7,1.7,1.7,1.7c0.5,0,0.9-0.2,1.2-0.6l0.3,0.2c-0.4,0.4-0.8,0.7-1.5,0.7
|
||||
C114.4,166.3,113.5,165.5,113.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M118.7,166.2v-3.7h-1.3v-0.3h2.9v0.3H119v3.7H118.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1" points="26.3,163.8 31.6,158.5 36.9,163.8 37.7,163.8 31.6,157.6 25.5,163.8 "/>
|
||||
<polygon class="st1" points="36.9,164.7 31.6,170 26.3,164.7 25.5,164.7 31.6,170.8 37.7,164.7 "/>
|
||||
<polygon class="st1" points="31,163.8 36.3,158.5 41.6,163.8 42.5,163.8 36.3,157.6 30.2,163.8 "/>
|
||||
<polygon class="st1" points="41.6,164.7 36.3,170 31,164.7 30.2,164.7 36.3,170.8 42.5,164.7 "/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M33.2,100.7c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3S37.8,100.7,33.2,100.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M33.2,35.2c40.7,0,73.8,33.1,73.8,73.8c0,0.7,0,1.4,0,2.1c0,1.7,0.6,3.3,1.7,4.6c1.2,1.2,2.8,1.9,4.5,2
|
||||
l0.2,0c3.5,0,6.3-2.7,6.4-6.2c0-0.8,0-1.7,0-2.5c0-47.7-38.8-86.6-86.6-86.6c-0.8,0-1.7,0-2.5,0c-1.7,0-3.3,0.8-4.5,2
|
||||
c-1.2,1.2-1.8,2.9-1.7,4.6c0.1,3.5,3,6.3,6.6,6.2C31.8,35.2,32.5,35.2,33.2,35.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M33.2,60.5c26.7,0,48.5,21.7,48.5,48.5c0,0.6,0,1.3,0,2c-0.1,1.7,0.5,3.3,1.7,4.6c1.2,1.3,2.7,2,4.4,2.1
|
||||
c1.7,0.1,3.3-0.5,4.6-1.7c1.2-1.2,2-2.7,2-4.4c0-0.9,0.1-1.8,0.1-2.6c0-33.8-27.5-61.2-61.2-61.2c-0.8,0-1.6,0-2.6,0.1
|
||||
c-1.7,0.1-3.3,0.8-4.4,2.1c-1.2,1.3-1.8,2.9-1.7,4.6s0.8,3.3,2.1,4.4c1.3,1.2,2.9,1.8,4.6,1.7C31.9,60.5,32.6,60.5,33.2,60.5z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st4" d="M33.2,86.7c12.3,0,22.3,10,22.3,22.3c0,0.5,0,1.1-0.1,1.8c-0.3,3.5,2.3,6.6,5.8,6.9
|
||||
c3.5,0.3,6.6-2.3,6.9-5.8c0.1-1,0.1-1.9,0.1-2.8c0-19.3-15.7-35.1-35.1-35.1c-0.9,0-1.8,0-2.8,0.1c-1.7,0.1-3.2,0.9-4.3,2.2
|
||||
c-1.1,1.3-1.6,2.9-1.5,4.6c0.1,1.7,0.9,3.2,2.2,4.3c1.3,1.1,2.9,1.6,4.6,1.5C32.1,86.7,32.7,86.7,33.2,86.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M35.8,130.4c1.1,0.6,2.1,1.5,2.7,2.6c0.7,1.1,1,2.3,1,3.7s-0.3,2.6-1,3.7c-0.7,1.1-1.6,2-2.7,2.6
|
||||
c-1.1,0.6-2.4,1-3.8,1s-2.7-0.3-3.8-1c-1.1-0.6-2.1-1.5-2.7-2.6c-0.7-1.1-1-2.3-1-3.7c0-1.3,0.3-2.6,1-3.7c0.7-1.1,1.6-2,2.7-2.6
|
||||
c1.1-0.6,2.4-0.9,3.8-0.9C33.4,129.5,34.7,129.8,35.8,130.4z M29.9,132.9c-0.7,0.4-1.2,0.9-1.6,1.6s-0.6,1.4-0.6,2.2
|
||||
c0,0.8,0.2,1.6,0.6,2.3c0.4,0.7,0.9,1.2,1.6,1.6c0.7,0.4,1.4,0.6,2.1,0.6c0.8,0,1.5-0.2,2.1-0.6c0.6-0.4,1.2-0.9,1.5-1.6
|
||||
c0.4-0.7,0.6-1.4,0.6-2.3c0-0.8-0.2-1.6-0.6-2.2s-0.9-1.2-1.5-1.6c-0.6-0.4-1.4-0.6-2.1-0.6C31.3,132.3,30.6,132.5,29.9,132.9z"/>
|
||||
<path class="st1" d="M50.6,133.6c0.8,0.5,1.4,1.1,1.8,2c0.4,0.8,0.6,1.8,0.6,2.9c0,1.1-0.2,2-0.6,2.8c-0.4,0.8-1,1.5-1.8,1.9
|
||||
c-0.8,0.5-1.6,0.7-2.6,0.7c-0.7,0-1.4-0.1-2-0.4s-1.1-0.7-1.5-1.2v5.4h-3.1V133h3.1v1.6c0.4-0.5,0.9-1,1.4-1.2s1.2-0.4,2-0.4
|
||||
C48.9,132.9,49.8,133.1,50.6,133.6z M49.1,140.5c0.5-0.6,0.7-1.3,0.7-2.2c0-0.9-0.2-1.6-0.7-2.1c-0.5-0.6-1.1-0.8-1.9-0.8
|
||||
s-1.4,0.3-1.9,0.8c-0.5,0.6-0.8,1.3-0.8,2.1c0,0.9,0.2,1.6,0.8,2.2s1.1,0.8,1.9,0.8S48.6,141,49.1,140.5z"/>
|
||||
<path class="st1" d="M63.4,134.4c0.9,1,1.4,2.4,1.4,4.2c0,0.3,0,0.6,0,0.7H57c0.2,0.7,0.5,1.2,1,1.6c0.5,0.4,1.1,0.6,1.8,0.6
|
||||
c0.5,0,1-0.1,1.5-0.3s0.9-0.5,1.3-0.9l1.6,1.6c-0.5,0.6-1.2,1.1-2,1.4c-0.8,0.3-1.6,0.5-2.6,0.5c-1.1,0-2.1-0.2-3-0.7
|
||||
s-1.5-1.1-2-1.9c-0.5-0.8-0.7-1.8-0.7-2.9c0-1.1,0.2-2.1,0.7-2.9s1.1-1.5,2-1.9c0.8-0.5,1.8-0.7,2.9-0.7
|
||||
C61.2,132.9,62.5,133.4,63.4,134.4z M61.8,137.5c0-0.7-0.3-1.3-0.7-1.7s-1-0.6-1.7-0.6c-0.7,0-1.2,0.2-1.7,0.6
|
||||
c-0.4,0.4-0.7,1-0.9,1.7H61.8z"/>
|
||||
<path class="st1" d="M76.2,134c0.7,0.7,1.1,1.7,1.1,3v6.8h-3.1v-5.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.5-0.6
|
||||
c-0.8,0-1.4,0.3-1.8,0.8c-0.4,0.5-0.7,1.2-0.7,2v5.3h-3.1V133h3.1v1.9c0.7-1.3,2-2,3.7-2C74.6,132.8,75.5,133.2,76.2,134z"/>
|
||||
<path class="st1" d="M96,129.7h3.3l-4.7,14h-3.3l-2.9-10.1l-3,10.1h-3.2l-4.7-14h3.4l3,10.7l3-10.7H90l3.1,10.7L96,129.7z"/>
|
||||
<path class="st1" d="M103.3,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C102.6,128.2,103,128.3,103.3,128.7z M100.6,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
<path class="st1" d="M106.5,129.7h10.1l0,2.6h-6.9v3.4h6.3v2.6h-6.3v5.3h-3.2V129.7z"/>
|
||||
<path class="st1" d="M120.9,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C120.1,128.2,120.5,128.3,120.9,128.7z M118.1,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,201 +0,0 @@
|
||||
import {
|
||||
cifUs,
|
||||
cifBr,
|
||||
cifIn,
|
||||
cifFr,
|
||||
cifEs,
|
||||
cifPl,
|
||||
cilAlignCenter,
|
||||
cilAlignLeft,
|
||||
cilAlignRight,
|
||||
cilApplicationsSettings,
|
||||
cilArrowRight,
|
||||
cilArrowTop,
|
||||
cilAsterisk,
|
||||
cilBan,
|
||||
cilBasket,
|
||||
cilBell,
|
||||
cilBold,
|
||||
cilBookmark,
|
||||
cilCalculator,
|
||||
cilCalendar,
|
||||
cilCloudDownload,
|
||||
cilChartPie,
|
||||
cilCheck,
|
||||
cilChevronBottom,
|
||||
cilChevronLeft,
|
||||
cilChevronRight,
|
||||
cilChevronTop,
|
||||
cilCircle,
|
||||
cilCheckCircle,
|
||||
cilCode,
|
||||
cilCommentSquare,
|
||||
cilCreditCard,
|
||||
cilCursor,
|
||||
cilCursorMove,
|
||||
cilDrop,
|
||||
cilDollar,
|
||||
cilEnvelopeClosed,
|
||||
cilEnvelopeLetter,
|
||||
cilEnvelopeOpen,
|
||||
cilEuro,
|
||||
cilGlobeAlt,
|
||||
cilGrid,
|
||||
cilFile,
|
||||
cilFullscreen,
|
||||
cilFullscreenExit,
|
||||
cilGraph,
|
||||
cilHome,
|
||||
cilInbox,
|
||||
cilIndentDecrease,
|
||||
cilIndentIncrease,
|
||||
cilInputPower,
|
||||
cilItalic,
|
||||
cilJustifyCenter,
|
||||
cilJustifyLeft,
|
||||
cilLaptop,
|
||||
cilLayers,
|
||||
cilLightbulb,
|
||||
cilList,
|
||||
cilListNumbered,
|
||||
cilListRich,
|
||||
cilLocationPin,
|
||||
cilLockLocked,
|
||||
cilMagnifyingGlass,
|
||||
cilMap,
|
||||
cilMoon,
|
||||
cilNotes,
|
||||
cilOptions,
|
||||
cilPaperclip,
|
||||
cilPaperPlane,
|
||||
cilPencil,
|
||||
cilPeople,
|
||||
cilPhone,
|
||||
cilPrint,
|
||||
cilPuzzle,
|
||||
cilRouter,
|
||||
cilSave,
|
||||
cilScrubber,
|
||||
cilSettings,
|
||||
cilShare,
|
||||
cilShareAll,
|
||||
cilShareBoxed,
|
||||
cilShieldAlt,
|
||||
cilSpeech,
|
||||
cilSpeedometer,
|
||||
cilSpreadsheet,
|
||||
cilStar,
|
||||
cilSun,
|
||||
cilTags,
|
||||
cilTask,
|
||||
cilTrash,
|
||||
cilUnderline,
|
||||
cilUser,
|
||||
cilUserFemale,
|
||||
cilUserFollow,
|
||||
cilUserUnfollow,
|
||||
cilX,
|
||||
cilXCircle,
|
||||
cilWarning,
|
||||
} from '@coreui/icons';
|
||||
|
||||
export const icons = {
|
||||
cilAlignCenter,
|
||||
cilAlignLeft,
|
||||
cilAlignRight,
|
||||
cilApplicationsSettings,
|
||||
cilArrowRight,
|
||||
cilArrowTop,
|
||||
cilAsterisk,
|
||||
cilBan,
|
||||
cilBasket,
|
||||
cilBell,
|
||||
cilBold,
|
||||
cilBookmark,
|
||||
cilCalculator,
|
||||
cilCalendar,
|
||||
cilCloudDownload,
|
||||
cilChartPie,
|
||||
cilCheck,
|
||||
cilChevronBottom,
|
||||
cilChevronLeft,
|
||||
cilChevronRight,
|
||||
cilChevronTop,
|
||||
cilCircle,
|
||||
cilCheckCircle,
|
||||
cilCode,
|
||||
cilCommentSquare,
|
||||
cilCreditCard,
|
||||
cilCursor,
|
||||
cilCursorMove,
|
||||
cilDrop,
|
||||
cilDollar,
|
||||
cilEnvelopeClosed,
|
||||
cilEnvelopeLetter,
|
||||
cilEnvelopeOpen,
|
||||
cilEuro,
|
||||
cilGlobeAlt,
|
||||
cilGrid,
|
||||
cilFile,
|
||||
cilFullscreen,
|
||||
cilFullscreenExit,
|
||||
cilGraph,
|
||||
cilHome,
|
||||
cilInbox,
|
||||
cilIndentDecrease,
|
||||
cilIndentIncrease,
|
||||
cilInputPower,
|
||||
cilItalic,
|
||||
cilJustifyCenter,
|
||||
cilJustifyLeft,
|
||||
cilLaptop,
|
||||
cilLayers,
|
||||
cilLightbulb,
|
||||
cilList,
|
||||
cilListNumbered,
|
||||
cilListRich,
|
||||
cilLocationPin,
|
||||
cilLockLocked,
|
||||
cilMagnifyingGlass,
|
||||
cilMap,
|
||||
cilMoon,
|
||||
cilNotes,
|
||||
cilOptions,
|
||||
cilPaperclip,
|
||||
cilPaperPlane,
|
||||
cilPencil,
|
||||
cilPeople,
|
||||
cilPhone,
|
||||
cilPrint,
|
||||
cilPuzzle,
|
||||
cilRouter,
|
||||
cilSave,
|
||||
cilScrubber,
|
||||
cilSettings,
|
||||
cilShare,
|
||||
cilShareAll,
|
||||
cilShareBoxed,
|
||||
cilShieldAlt,
|
||||
cilSpeech,
|
||||
cilSpeedometer,
|
||||
cilSpreadsheet,
|
||||
cilStar,
|
||||
cilSun,
|
||||
cilTags,
|
||||
cilTask,
|
||||
cilTrash,
|
||||
cilUnderline,
|
||||
cilUser,
|
||||
cilUserFemale,
|
||||
cilUserFollow,
|
||||
cilUserUnfollow,
|
||||
cilX,
|
||||
cilXCircle,
|
||||
cilWarning,
|
||||
cifUs,
|
||||
cifBr,
|
||||
cifIn,
|
||||
cifFr,
|
||||
cifEs,
|
||||
cifPl,
|
||||
};
|
||||
@@ -1,215 +0,0 @@
|
||||
import {
|
||||
CButton,
|
||||
CModal,
|
||||
CModalHeader,
|
||||
CModalTitle,
|
||||
CModalBody,
|
||||
CModalFooter,
|
||||
CSwitch,
|
||||
CCol,
|
||||
CRow,
|
||||
CFormGroup,
|
||||
CInputRadio,
|
||||
CLabel,
|
||||
CPopover,
|
||||
} from '@coreui/react';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { cilX } from '@coreui/icons';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import DatePicker from 'react-widgets/DatePicker';
|
||||
import PropTypes from 'prop-types';
|
||||
import { dateToUnix } from 'utils/helper';
|
||||
import 'react-widgets/styles.css';
|
||||
import axiosInstance from 'utils/axiosInstance';
|
||||
import eventBus from 'utils/eventBus';
|
||||
import SuccessfulActionModalBody from 'components/SuccessfulActionModalBody';
|
||||
import { LoadingButton, useAuth, useDevice, useToast } from 'ucentral-libs';
|
||||
|
||||
const BlinkModal = ({ show, toggleModal }) => {
|
||||
const { t } = useTranslation();
|
||||
const { currentToken, endpoints } = useAuth();
|
||||
const { deviceSerialNumber } = useDevice();
|
||||
const { addToast } = useToast();
|
||||
const [isNow, setIsNow] = useState(false);
|
||||
const [waiting, setWaiting] = useState(false);
|
||||
const [chosenDate, setChosenDate] = useState(new Date().toString());
|
||||
const [chosenPattern, setPattern] = useState('on');
|
||||
const [result, setResult] = useState(null);
|
||||
|
||||
const toggleNow = () => {
|
||||
setIsNow(!isNow);
|
||||
};
|
||||
|
||||
const setDate = (date) => {
|
||||
if (date) {
|
||||
setChosenDate(date.toString());
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
setWaiting(false);
|
||||
setChosenDate(new Date().toString());
|
||||
setPattern('on');
|
||||
setResult(null);
|
||||
}
|
||||
}, [show]);
|
||||
|
||||
const doAction = () => {
|
||||
setWaiting(true);
|
||||
const utcDate = new Date(chosenDate);
|
||||
|
||||
const parameters = {
|
||||
serialNumber: deviceSerialNumber,
|
||||
when: isNow ? 0 : dateToUnix(utcDate),
|
||||
pattern: chosenPattern,
|
||||
duration: 30,
|
||||
};
|
||||
|
||||
const headers = {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
};
|
||||
|
||||
axiosInstance
|
||||
.post(
|
||||
`${endpoints.owgw}/api/v1/device/${encodeURIComponent(deviceSerialNumber)}/leds`,
|
||||
parameters,
|
||||
{ headers },
|
||||
)
|
||||
.then(() => {
|
||||
addToast({
|
||||
title: t('common.success'),
|
||||
body: t('commands.command_success'),
|
||||
color: 'success',
|
||||
autohide: true,
|
||||
});
|
||||
toggleModal();
|
||||
})
|
||||
.catch(() => {
|
||||
setResult('error');
|
||||
})
|
||||
.finally(() => {
|
||||
setWaiting(false);
|
||||
eventBus.dispatch('actionCompleted', { message: 'An action has been completed' });
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<CModal show={show} onClose={toggleModal}>
|
||||
<CModalHeader className="p-1">
|
||||
<CModalTitle className="pl-1 pt-1">{t('blink.device_leds')}</CModalTitle>
|
||||
<div className="text-right">
|
||||
<CPopover content={t('common.close')}>
|
||||
<CButton color="primary" variant="outline" className="ml-2" onClick={toggleModal}>
|
||||
<CIcon content={cilX} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</div>
|
||||
</CModalHeader>
|
||||
{result === 'success' ? (
|
||||
<SuccessfulActionModalBody toggleModal={toggleModal} />
|
||||
) : (
|
||||
<div>
|
||||
<CModalBody>
|
||||
<CFormGroup row>
|
||||
<CCol md="3">
|
||||
<CLabel>{t('blink.pattern')}</CLabel>
|
||||
</CCol>
|
||||
<CCol>
|
||||
<CFormGroup variant="custom-radio" onClick={() => setPattern('on')} inline>
|
||||
<CInputRadio
|
||||
custom
|
||||
defaultChecked={chosenPattern === 'on'}
|
||||
id="radio1"
|
||||
name="radios"
|
||||
value="option1"
|
||||
/>
|
||||
<CLabel variant="custom-checkbox" htmlFor="radio1">
|
||||
{t('common.on')}
|
||||
</CLabel>
|
||||
</CFormGroup>
|
||||
<CFormGroup variant="custom-radio" onClick={() => setPattern('off')} inline>
|
||||
<CInputRadio
|
||||
custom
|
||||
defaultChecked={chosenPattern === 'off'}
|
||||
id="radio2"
|
||||
name="radios"
|
||||
value="option2"
|
||||
/>
|
||||
<CLabel variant="custom-checkbox" htmlFor="radio2">
|
||||
{t('common.off')}
|
||||
</CLabel>
|
||||
</CFormGroup>
|
||||
<CFormGroup variant="custom-radio" onClick={() => setPattern('blink')} inline>
|
||||
<CInputRadio
|
||||
custom
|
||||
defaultChecked={chosenPattern === 'blink'}
|
||||
id="radio3"
|
||||
name="radios"
|
||||
value="option3"
|
||||
/>
|
||||
<CLabel variant="custom-checkbox" htmlFor="radio3">
|
||||
{t('blink.blink')}
|
||||
</CLabel>
|
||||
</CFormGroup>
|
||||
</CCol>
|
||||
</CFormGroup>
|
||||
<CRow className="pt-1">
|
||||
<CCol md="8">
|
||||
<p>{t('blink.execute_now')}</p>
|
||||
</CCol>
|
||||
<CCol>
|
||||
<CSwitch
|
||||
disabled={waiting}
|
||||
color="primary"
|
||||
defaultChecked={isNow}
|
||||
onClick={toggleNow}
|
||||
labelOn={t('common.yes')}
|
||||
labelOff={t('common.no')}
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<CRow hidden={isNow} className="pt-3">
|
||||
<CCol md="4" className="pt-2">
|
||||
<p>{t('common.custom_date')}</p>
|
||||
</CCol>
|
||||
<CCol xs="12" md="8">
|
||||
<DatePicker
|
||||
selected={new Date(chosenDate)}
|
||||
includeTime
|
||||
value={new Date(chosenDate)}
|
||||
placeholder="Select custom date"
|
||||
disabled={waiting}
|
||||
onChange={(date) => setDate(date)}
|
||||
min={new Date()}
|
||||
/>
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CModalBody>
|
||||
<CModalFooter>
|
||||
<LoadingButton
|
||||
label={isNow ? t('blink.set_leds') : t('common.schedule')}
|
||||
isLoadingLabel={t('common.loading_ellipsis')}
|
||||
isLoading={waiting}
|
||||
action={doAction}
|
||||
block={false}
|
||||
disabled={waiting}
|
||||
/>
|
||||
<CButton color="secondary" onClick={toggleModal}>
|
||||
{t('common.cancel')}
|
||||
</CButton>
|
||||
</CModalFooter>
|
||||
</div>
|
||||
)}
|
||||
</CModal>
|
||||
);
|
||||
};
|
||||
|
||||
BlinkModal.propTypes = {
|
||||
show: PropTypes.bool.isRequired,
|
||||
toggleModal: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default BlinkModal;
|
||||
50
src/components/Buttons/AlertButton/index.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { Warning } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ThemeProps } from 'models/Theme';
|
||||
|
||||
export interface AlertButtonProps extends ThemeProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
const _AlertButton: React.FC<AlertButtonProps> = ({ onClick, isDisabled, isLoading, isCompact, label, ...props }) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme="red"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
rightIcon={<Warning size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
>
|
||||
{label ?? t('common.alert')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={label ?? t('common.alert')}>
|
||||
<IconButton
|
||||
aria-label="alert-button"
|
||||
colorScheme="red"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
icon={<Warning size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const AlertButton = React.memo(_AlertButton);
|
||||
28
src/components/Buttons/CloseButton/index.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { IconButton, SpaceProps } from '@chakra-ui/react';
|
||||
import { X } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface CloseButtonProps extends SpaceProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const _CloseButton: React.FC<CloseButtonProps> = ({ onClick, isDisabled, isLoading, ...props }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
aria-label={t('common.close')}
|
||||
colorScheme="gray"
|
||||
onClick={onClick}
|
||||
icon={<X size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const CloseButton = React.memo(_CloseButton);
|
||||
49
src/components/Buttons/CreateButton/index.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint, SpaceProps } from '@chakra-ui/react';
|
||||
import { Plus } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface CreateButtonProps extends SpaceProps {
|
||||
onClick?: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
const _CreateButton: React.FC<CreateButtonProps> = ({ onClick, isDisabled, isLoading, isCompact, label, ...props }) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
rightIcon={<Plus size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
>
|
||||
{label ?? t('common.create')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={label ?? t('common.create')}>
|
||||
<IconButton
|
||||
aria-label="Create"
|
||||
colorScheme="blue"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
icon={<Plus size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const CreateButton = React.memo(_CreateButton);
|
||||
61
src/components/Buttons/DeleteButton/index.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { Trash } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface DeleteButtonProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
label?: string;
|
||||
ml?: string | number;
|
||||
}
|
||||
|
||||
const _DeleteButton: React.FC<DeleteButtonProps> = ({
|
||||
onClick,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
label,
|
||||
ml,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
type="button"
|
||||
colorScheme="red"
|
||||
onClick={onClick}
|
||||
rightIcon={<Trash size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
>
|
||||
{label ?? t('crud.delete')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip label={label ?? t('crud.delete')}>
|
||||
<IconButton
|
||||
colorScheme="red"
|
||||
aria-label="delete"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
icon={<Trash size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const DeleteButton = React.memo(_DeleteButton);
|
||||
211
src/components/Buttons/DeviceActionDropdown/index.tsx
Normal file
@@ -0,0 +1,211 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Portal,
|
||||
Spinner,
|
||||
Tooltip,
|
||||
useToast,
|
||||
} from '@chakra-ui/react';
|
||||
import axios from 'axios';
|
||||
import { Wrench } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useControllerStore } from 'contexts/ControllerSocketProvider/useStore';
|
||||
import { useBlinkDevice, useGetDeviceRtty } from 'hooks/Network/Devices';
|
||||
import { useUpdateDeviceToLatest } from 'hooks/Network/Firmware';
|
||||
import { useMutationResult } from 'hooks/useMutationResult';
|
||||
import { GatewayDevice } from 'models/Device';
|
||||
|
||||
interface Props {
|
||||
device: GatewayDevice;
|
||||
refresh: () => void;
|
||||
isDisabled?: boolean;
|
||||
onOpenScan: (serialNumber: string) => void;
|
||||
onOpenFactoryReset: (serialNumber: string) => void;
|
||||
onOpenUpgradeModal: (serialNumber: string) => void;
|
||||
onOpenTrace: (serialNumber: string) => void;
|
||||
onOpenEventQueue: (serialNumber: string) => void;
|
||||
onOpenConfigureModal: (serialNumber: string) => void;
|
||||
onOpenTelemetryModal: (serialNumber: string) => void;
|
||||
onOpenScriptModal: (device: GatewayDevice) => void;
|
||||
onOpenRebootModal: (serialNumber: string) => void;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
isCompact?: boolean;
|
||||
}
|
||||
|
||||
const DeviceActionDropdown = ({
|
||||
device,
|
||||
refresh,
|
||||
isDisabled,
|
||||
onOpenScan,
|
||||
onOpenFactoryReset,
|
||||
onOpenTrace,
|
||||
onOpenUpgradeModal,
|
||||
onOpenEventQueue,
|
||||
onOpenTelemetryModal,
|
||||
onOpenConfigureModal,
|
||||
onOpenScriptModal,
|
||||
onOpenRebootModal,
|
||||
size,
|
||||
isCompact,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const toast = useToast();
|
||||
const addEventListeners = useControllerStore((state) => state.addEventListeners);
|
||||
const { refetch: getRtty, isInitialLoading: isRtty } = useGetDeviceRtty({
|
||||
serialNumber: device.serialNumber,
|
||||
extraId: 'inventory-modal',
|
||||
});
|
||||
const { mutateAsync: blink } = useBlinkDevice({ serialNumber: device.serialNumber });
|
||||
const { onSuccess: onBlinkSuccess, onError: onBlinkError } = useMutationResult({
|
||||
objName: t('devices.one'),
|
||||
operationType: 'blink',
|
||||
refresh,
|
||||
});
|
||||
const updateToLatest = useUpdateDeviceToLatest({ serialNumber: device.serialNumber, compatible: device.compatible });
|
||||
|
||||
const handleBlinkClick = () => {
|
||||
blink(undefined, {
|
||||
onError: (e) => {
|
||||
if (axios.isAxiosError(e)) onBlinkError(e);
|
||||
},
|
||||
});
|
||||
onBlinkSuccess();
|
||||
};
|
||||
const handleOpenScan = () => onOpenScan(device.serialNumber);
|
||||
const handleOpenFactoryReset = () => onOpenFactoryReset(device.serialNumber);
|
||||
const handleOpenUpgrade = () => onOpenUpgradeModal(device.serialNumber);
|
||||
const handleOpenTrace = () => onOpenTrace(device.serialNumber);
|
||||
const handleOpenQueue = () => onOpenEventQueue(device.serialNumber);
|
||||
const handleOpenConfigure = () => onOpenConfigureModal(device.serialNumber);
|
||||
const handleOpenTelemetry = () => onOpenTelemetryModal(device.serialNumber);
|
||||
const handleOpenScript = () => onOpenScriptModal(device);
|
||||
const handleUpdateToLatest = () => {
|
||||
updateToLatest.mutate(
|
||||
{ keepRedirector: true },
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast({
|
||||
id: `upgrade-to-latest-start-${device.serialNumber}`,
|
||||
title: t('common.success'),
|
||||
description: t('controller.devices.sent_upgrade_to_latest'),
|
||||
status: 'success',
|
||||
duration: 5000,
|
||||
isClosable: true,
|
||||
position: 'top-right',
|
||||
});
|
||||
addEventListeners([
|
||||
{
|
||||
id: `device-connection-upgrade-${device.serialNumber}`,
|
||||
type: 'DEVICE_CONNECTION',
|
||||
serialNumber: device.serialNumber,
|
||||
callback: () => {
|
||||
const id = `device-connection-upgrade-notification-${device.serialNumber}`;
|
||||
|
||||
if (!toast.isActive(id)) {
|
||||
toast({
|
||||
id,
|
||||
title: t('common.success'),
|
||||
description: t('controller.devices.finished_upgrade', { serialNumber: device.serialNumber }),
|
||||
status: 'success',
|
||||
duration: 5000,
|
||||
isClosable: true,
|
||||
position: 'top-right',
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
id: `device-disconnected-upgrade-${device.serialNumber}`,
|
||||
type: 'DEVICE_DISCONNECTION',
|
||||
serialNumber: device.serialNumber,
|
||||
callback: () => {
|
||||
const id = `device-disconnection-upgrade-notification-${device.serialNumber}`;
|
||||
|
||||
if (!toast.isActive(id)) {
|
||||
toast({
|
||||
id,
|
||||
title: t('common.success'),
|
||||
description: t('controller.devices.started_upgrade', { serialNumber: device.serialNumber }),
|
||||
status: 'success',
|
||||
duration: 5000,
|
||||
isClosable: true,
|
||||
position: 'top-right',
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
},
|
||||
onError: (e) => {
|
||||
if (axios.isAxiosError(e)) {
|
||||
toast({
|
||||
id: `upgrade-to-latest-error-${device.serialNumber}`,
|
||||
title: t('common.error'),
|
||||
description: e?.response?.data?.ErrorDescription,
|
||||
status: 'error',
|
||||
duration: 5000,
|
||||
isClosable: true,
|
||||
position: 'top-right',
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleConnectClick = () => getRtty();
|
||||
const handleRebootClick = () => onOpenRebootModal(device.serialNumber);
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<Tooltip label={t('commands.other')}>
|
||||
{size === undefined || isCompact ? (
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
aria-label="Commands"
|
||||
icon={isRtty ? <Spinner /> : <Wrench size={20} />}
|
||||
size={size ?? 'sm'}
|
||||
isDisabled={isDisabled}
|
||||
ml={2}
|
||||
/>
|
||||
) : (
|
||||
<MenuButton
|
||||
as={Button}
|
||||
aria-label="Commands"
|
||||
rightIcon={isRtty ? <Spinner /> : <Wrench size={20} />}
|
||||
size={size ?? 'sm'}
|
||||
isDisabled={isDisabled}
|
||||
ml={2}
|
||||
>
|
||||
{t('commands.other')}
|
||||
</MenuButton>
|
||||
)}
|
||||
</Tooltip>
|
||||
<Portal>
|
||||
<MenuList>
|
||||
<MenuItem onClick={handleBlinkClick}>{t('commands.blink')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenConfigure}>{t('controller.configure.title')}</MenuItem>
|
||||
<MenuItem onClick={handleConnectClick}>{t('commands.connect')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenQueue}>{t('controller.queue.title')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenFactoryReset}>{t('commands.factory_reset')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenUpgrade}>{t('commands.firmware_upgrade')}</MenuItem>
|
||||
<MenuItem onClick={handleRebootClick}>{t('commands.reboot')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenTelemetry}>{t('controller.telemetry.title')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenScript}>{t('script.one')}</MenuItem>
|
||||
<MenuItem onClick={handleOpenTrace}>{t('controller.devices.trace')}</MenuItem>
|
||||
<MenuItem onClick={handleUpdateToLatest} hidden>
|
||||
{t('premium.toolbox.upgrade_to_latest')}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleOpenScan}>{t('commands.wifiscan')}</MenuItem>
|
||||
</MenuList>
|
||||
</Portal>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(DeviceActionDropdown);
|
||||
46
src/components/Buttons/EditButton/index.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { IconButton, Button, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { Pen } from 'phosphor-react';
|
||||
|
||||
export interface EditButtonProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
label?: string;
|
||||
ml?: string | number;
|
||||
}
|
||||
|
||||
const _EditButton: React.FC<EditButtonProps> = ({ onClick, label, isDisabled, isLoading, isCompact, ...props }) => {
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme="gray"
|
||||
onClick={onClick}
|
||||
rightIcon={<Pen size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<IconButton
|
||||
aria-label="edit"
|
||||
colorScheme="gray"
|
||||
onClick={onClick}
|
||||
icon={<Pen size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const EditButton = React.memo(_EditButton);
|
||||
79
src/components/Buttons/FileInputButton/index.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FormControl, Input, InputGroup } from '@chakra-ui/react';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
export interface FileInputButtonProps {
|
||||
value: string;
|
||||
setValue: (v: string, file?: File) => void;
|
||||
setFileName?: (v: string) => void;
|
||||
refreshId: string;
|
||||
accept: string;
|
||||
isHidden?: boolean;
|
||||
isStringFile?: boolean;
|
||||
sizeLimit?: number;
|
||||
}
|
||||
|
||||
const _FileInputButton: React.FC<FileInputButtonProps> = ({
|
||||
value,
|
||||
setValue,
|
||||
setFileName,
|
||||
refreshId,
|
||||
accept,
|
||||
isHidden,
|
||||
isStringFile,
|
||||
sizeLimit,
|
||||
}) => {
|
||||
const [fileKey, setFileKey] = useState(uuid());
|
||||
let fileReader: FileReader | undefined;
|
||||
|
||||
const handleStringFileRead = () => {
|
||||
if (fileReader) {
|
||||
const content = fileReader.result;
|
||||
if (content) {
|
||||
setValue(content as string);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files ? e.target.files[0] : undefined;
|
||||
if (file) {
|
||||
if (sizeLimit && file.size > sizeLimit) {
|
||||
setFileKey(uuid());
|
||||
} else {
|
||||
const newVal = URL.createObjectURL(file);
|
||||
if (!isStringFile) {
|
||||
setValue(newVal, file);
|
||||
if (setFileName) setFileName(file.name ?? '');
|
||||
} else {
|
||||
fileReader = new FileReader();
|
||||
if (setFileName) setFileName(file.name);
|
||||
fileReader.onloadend = handleStringFileRead;
|
||||
fileReader.readAsText(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (value === '') setFileKey(uuid());
|
||||
}, [refreshId, value]);
|
||||
|
||||
return (
|
||||
<FormControl hidden={isHidden}>
|
||||
<InputGroup>
|
||||
<Input
|
||||
borderRadius="15px"
|
||||
pt={1}
|
||||
fontSize="sm"
|
||||
type="file"
|
||||
onChange={changeFile}
|
||||
key={fileKey}
|
||||
accept={accept}
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export const FileInputButton = React.memo(_FileInputButton);
|
||||
62
src/components/Buttons/RefreshButton/index.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, ThemeTypings, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { ArrowsClockwise } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface RefreshButtonProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isFetching?: boolean;
|
||||
isCompact?: boolean;
|
||||
ml?: string | number;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
colorScheme?: ThemeTypings['colorSchemes'];
|
||||
}
|
||||
|
||||
const _RefreshButton: React.FC<RefreshButtonProps> = ({
|
||||
onClick,
|
||||
isDisabled,
|
||||
isFetching,
|
||||
isCompact,
|
||||
ml,
|
||||
size,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
minWidth="112px"
|
||||
colorScheme="gray"
|
||||
onClick={onClick}
|
||||
rightIcon={<ArrowsClockwise size={20} />}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={isFetching}
|
||||
ml={ml}
|
||||
size={size}
|
||||
{...props}
|
||||
>
|
||||
{t('common.refresh')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip label={t('common.refresh')}>
|
||||
<IconButton
|
||||
aria-label="refresh"
|
||||
colorScheme="gray"
|
||||
onClick={onClick}
|
||||
icon={<ArrowsClockwise size={20} />}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={isFetching}
|
||||
ml={ml}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const RefreshButton = React.memo(_RefreshButton);
|
||||
59
src/components/Buttons/ResponsiveButton/index.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, SpaceProps, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
|
||||
export interface ResponsiveButtonProps extends SpaceProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
color: string;
|
||||
label: string;
|
||||
icon?: React.ReactElement;
|
||||
}
|
||||
|
||||
const _ResponsiveButton: React.FC<ResponsiveButtonProps> = ({
|
||||
onClick,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
color,
|
||||
label,
|
||||
icon,
|
||||
...props
|
||||
}) => {
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme={color}
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
// @ts-ignore
|
||||
rightIcon={icon}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<IconButton
|
||||
aria-label={label}
|
||||
colorScheme={color}
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
// @ts-ignore
|
||||
icon={icon}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const ResponsiveButton = React.memo(_ResponsiveButton);
|
||||
60
src/components/Buttons/SaveButton/index.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { FloppyDisk } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface SaveButtonProps
|
||||
extends React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
isDirty?: boolean;
|
||||
dirtyCheck?: boolean;
|
||||
ml?: string | number;
|
||||
}
|
||||
|
||||
const _SaveButton: React.FC<SaveButtonProps> = ({
|
||||
onClick,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
isDirty,
|
||||
dirtyCheck,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
type="submit"
|
||||
onClick={onClick}
|
||||
rightIcon={<FloppyDisk size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled || (dirtyCheck && !isDirty)}
|
||||
{...props}
|
||||
>
|
||||
{t('common.save')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={t('common.save')}>
|
||||
<IconButton
|
||||
aria-label="save"
|
||||
colorScheme="blue"
|
||||
type="submit"
|
||||
onClick={onClick}
|
||||
icon={<FloppyDisk size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled || (dirtyCheck && !isDirty)}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const SaveButton = React.memo(_SaveButton);
|
||||
78
src/components/Buttons/StepButton/index.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { ArrowRight, FloppyDisk } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface StepButtonProps {
|
||||
onNext: () => void;
|
||||
onSave?: () => void;
|
||||
currentStep: number;
|
||||
lastStep: number;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
ml?: string | number;
|
||||
}
|
||||
|
||||
const _StepButton: React.FC<StepButtonProps> = ({
|
||||
onNext,
|
||||
onSave,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
currentStep,
|
||||
lastStep,
|
||||
ml,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
const onClick = useCallback(
|
||||
() => (currentStep === lastStep && onSave ? onSave() : onNext()),
|
||||
[currentStep, lastStep, onNext, onSave],
|
||||
);
|
||||
const icon = useMemo(
|
||||
() => (currentStep === lastStep ? <FloppyDisk size={20} /> : <ArrowRight size={20} />),
|
||||
[currentStep, lastStep],
|
||||
);
|
||||
const label = useMemo(
|
||||
() => (currentStep === lastStep ? t('common.save') : t('common.next')),
|
||||
[currentStep, lastStep],
|
||||
);
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
type="button"
|
||||
colorScheme="blue"
|
||||
onClick={onClick}
|
||||
rightIcon={icon}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<IconButton
|
||||
colorScheme="blue"
|
||||
aria-label="next"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
icon={icon}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const StepButton = React.memo(_StepButton);
|
||||
83
src/components/Buttons/ToggleEditButton/index.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint, useDisclosure } from '@chakra-ui/react';
|
||||
import { Pencil, X } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ConfirmCloseAlertModal } from '../../Modals/ConfirmCloseAlert';
|
||||
|
||||
export interface ToggleEditButtonProps {
|
||||
toggleEdit: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
isEditing: boolean;
|
||||
isDirty?: boolean;
|
||||
ml?: string | number;
|
||||
}
|
||||
|
||||
const _ToggleEditButton: React.FC<ToggleEditButtonProps> = ({
|
||||
toggleEdit,
|
||||
isEditing,
|
||||
isDirty,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
ml,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
const { isOpen: showConfirm, onOpen: openConfirm, onClose: closeConfirm } = useDisclosure();
|
||||
|
||||
const toggle = () => {
|
||||
if (isEditing && isDirty) {
|
||||
openConfirm();
|
||||
} else {
|
||||
toggleEdit();
|
||||
}
|
||||
};
|
||||
|
||||
const closeCancelAndForm = () => {
|
||||
closeConfirm();
|
||||
toggleEdit();
|
||||
};
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
colorScheme="gray"
|
||||
type="button"
|
||||
onClick={toggle}
|
||||
rightIcon={isEditing ? <X size={20} /> : <Pencil size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
>
|
||||
{isEditing ? t('common.stop_editing') : t('common.edit')}
|
||||
</Button>
|
||||
<ConfirmCloseAlertModal isOpen={showConfirm} confirm={closeCancelAndForm} cancel={closeConfirm} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Tooltip label={isEditing ? t('common.stop_editing') : t('common.edit')}>
|
||||
<IconButton
|
||||
aria-label="toggle-edit"
|
||||
colorScheme="gray"
|
||||
type="button"
|
||||
onClick={toggle}
|
||||
icon={isEditing ? <X size={20} /> : <Pencil size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
ml={ml}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
<ConfirmCloseAlertModal isOpen={showConfirm} confirm={closeCancelAndForm} cancel={closeConfirm} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const ToggleEditButton = React.memo(_ToggleEditButton);
|
||||
57
src/components/Buttons/WarningButton/index.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||
import { Warning } from 'phosphor-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ThemeProps } from 'models/Theme';
|
||||
|
||||
export interface WarningButtonProps extends ThemeProps {
|
||||
onClick: () => void;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
isCompact?: boolean;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
const _WarningButton: React.FC<WarningButtonProps> = ({
|
||||
onClick,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isCompact,
|
||||
label,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const breakpoint = useBreakpoint();
|
||||
|
||||
if (!isCompact && breakpoint !== 'base' && breakpoint !== 'sm') {
|
||||
return (
|
||||
<Button
|
||||
colorScheme="yellow"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
rightIcon={<Warning size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
>
|
||||
{label ?? t('common.alert')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip label={label ?? t('common.alert')}>
|
||||
<IconButton
|
||||
aria-label="alert-button"
|
||||
colorScheme="yellow"
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
icon={<Warning size={20} />}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isDisabled}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const WarningButton = React.memo(_WarningButton);
|
||||
@@ -1,33 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CButton, CModal, CModalHeader, CModalBody, CModalTitle, CPopover } from '@coreui/react';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { cilX } from '@coreui/icons';
|
||||
|
||||
const DetailsModal = ({ t, show, toggle, details, commandUuid }) => (
|
||||
<CModal size="lg" show={show} onClose={toggle}>
|
||||
<CModalHeader className="p-1">
|
||||
<CModalTitle className="text-dark">{commandUuid}</CModalTitle>
|
||||
<div className="text-right">
|
||||
<CPopover content={t('common.close')}>
|
||||
<CButton color="primary" variant="outline" className="ml-2" onClick={toggle}>
|
||||
<CIcon content={cilX} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</div>
|
||||
</CModalHeader>
|
||||
<CModalBody>
|
||||
<pre className="ignore">{JSON.stringify(details, null, 2)}</pre>
|
||||
</CModalBody>
|
||||
</CModal>
|
||||
);
|
||||
|
||||
DetailsModal.propTypes = {
|
||||
t: PropTypes.func.isRequired,
|
||||
show: PropTypes.bool.isRequired,
|
||||
toggle: PropTypes.func.isRequired,
|
||||
details: PropTypes.instanceOf(Object).isRequired,
|
||||
commandUuid: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default DetailsModal;
|
||||