mirror of
https://github.com/serghey-rodin/vesta.git
synced 2025-08-20 13:24:24 -07:00
move react sources to src dir
This commit is contained in:
parent
8e97eb2dad
commit
08513755b2
346 changed files with 0 additions and 0 deletions
|
@ -1,68 +0,0 @@
|
|||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br>
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br>
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.<br>
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br>
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
14969
web/js/react/package-lock.json
generated
14969
web/js/react/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,51 +0,0 @@
|
|||
{
|
||||
"name": "react-control-panel",
|
||||
"author": "Alexander Osinskii",
|
||||
"email": "alexanderosinskii@gmail.com",
|
||||
"version": "1.0.0",
|
||||
"private": false,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.10.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.21",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.10.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.10.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.4",
|
||||
"axios": "^0.21.4",
|
||||
"bootstrap": "^4.3.1",
|
||||
"classname": "0.0.0",
|
||||
"dayjs": "^1.10.7",
|
||||
"jquery": "^3.5.1",
|
||||
"node-sass": "^4.14.1",
|
||||
"popper.js": "^1.15.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"qs": "^6.9.4",
|
||||
"react": "^16.10.2",
|
||||
"react-codemirror": "^1.0.0",
|
||||
"react-dom": "^16.10.2",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-html-parser": "^2.0.2",
|
||||
"react-redux": "^7.2.1",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "^3.4.1",
|
||||
"react-toastify": "^5.3.1",
|
||||
"redux": "^4.0.5",
|
||||
"redux-devtools-extension": "^2.13.8",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"validate.js": "^0.13.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
]
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1,24 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/images/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<title>Vesta</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
||||
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
|
||||
integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/backup/index.php';
|
||||
const scheduleBackupUri = '/api/v1/schedule/restore/';
|
||||
const backupDetailsUri = '/api/v1/list/backup/index.php';
|
||||
const backupExclusionsUri = '/api/v1/list/backup/exclusions/index.php';
|
||||
const backupExclusionsInfoUri = '/api/v1/edit/backup/exclusions/index.php';
|
||||
const backupRestoreSettingUri = '/api/v1/schedule/restore/index.php';
|
||||
const bulkRestoreUri = '/api/v1/bulk/restore/index.php';
|
||||
|
||||
export const getBackupList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, backups) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
backups.forEach(backup => {
|
||||
formData.append("backup[]", backup);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/backup/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const scheduleBackup = () => {
|
||||
return axios.get(BASE_URL + scheduleBackupUri);
|
||||
}
|
||||
|
||||
export const getBackupDetails = backup => {
|
||||
return axios.get(BASE_URL + `${backupDetailsUri}?backup=${backup}`);
|
||||
}
|
||||
|
||||
export const restoreBackupSetting = params => {
|
||||
return axios.get(BASE_URL + `${backupRestoreSettingUri}${params}`);
|
||||
}
|
||||
|
||||
export const bulkRestore = (action, selection, backup) => {
|
||||
const formData = new FormData();
|
||||
formData.append("token", getAuthToken());
|
||||
formData.append("action", action);
|
||||
formData.append("backup", backup);
|
||||
|
||||
selection.forEach(udir => {
|
||||
formData.append("udir[]", udir);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + `${bulkRestoreUri}`, formData);
|
||||
}
|
||||
|
||||
export const getBackupExclusions = () => {
|
||||
return axios.get(BASE_URL + `${backupExclusionsUri}`);
|
||||
}
|
||||
|
||||
export const getBackupExclusionsInfo = () => {
|
||||
return axios.get(BASE_URL + `${backupExclusionsInfoUri}`);
|
||||
}
|
||||
|
||||
export const updateBackupExclusions = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + backupExclusionsInfoUri, formDataObject, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/cron/index.php';
|
||||
const cronAddApiUri = '/api/v1/add/cron/index.php';
|
||||
const jobInfoUri = '/api/v1/edit/cron/index.php';
|
||||
const updateCronJobUri = '/api/v1/edit/cron/index.php';
|
||||
|
||||
export const getCronList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, domainNameSystems) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
domainNameSystems.forEach(domainNameSystem => {
|
||||
formData.append("job[]", domainNameSystem);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/cron/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addCronJob = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + cronAddApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getCronJobInfo = job => {
|
||||
return axios.get(BASE_URL + jobInfoUri, {
|
||||
params: {
|
||||
job,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateCronJob = (data, job) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateCronJobUri, formDataObject, {
|
||||
params: {
|
||||
job,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/db/index.php';
|
||||
const addDbApiUri = '/api/v1/add/db/index.php';
|
||||
const optionalDbInfoUri = '/api/v1/add/db/index.php';
|
||||
const dbInfoUri = '/api/v1/edit/db/index.php';
|
||||
const updateDatabaseUri = '/api/v1/edit/db/index.php';
|
||||
|
||||
export const getDatabaseList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, domainNameSystems) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
domainNameSystems.forEach(domainNameSystem => {
|
||||
formData.append("database[]", domainNameSystem);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/db/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getDbOptionalInfo = () => {
|
||||
return axios.get(BASE_URL + optionalDbInfoUri);
|
||||
}
|
||||
|
||||
export const addDatabase = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addDbApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const dbCharsets = [
|
||||
'big5',
|
||||
'dec8',
|
||||
'cp850',
|
||||
'hp8',
|
||||
'koi8r',
|
||||
'latin1',
|
||||
'latin2',
|
||||
'swe7',
|
||||
'ascii',
|
||||
'ujis',
|
||||
'sjis',
|
||||
'hebrew',
|
||||
'tis620',
|
||||
'euckr',
|
||||
'koi8u',
|
||||
'gb2312',
|
||||
'greek',
|
||||
'cp1250',
|
||||
'gbk',
|
||||
'latin5',
|
||||
'armscii8',
|
||||
'utf8',
|
||||
'ucs2',
|
||||
'cp866',
|
||||
'keybcs2',
|
||||
'macce',
|
||||
'macroman',
|
||||
'cp852',
|
||||
'latin7',
|
||||
'cp1251',
|
||||
'cp1256',
|
||||
'cp1257',
|
||||
'binary',
|
||||
'geostd8',
|
||||
'cp932',
|
||||
'eucjpms'
|
||||
];
|
||||
|
||||
export const getDatabaseInfo = database => {
|
||||
return axios.get(BASE_URL + dbInfoUri, {
|
||||
params: {
|
||||
database,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateDatabase = (data, database) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateDatabaseUri, formDataObject, {
|
||||
params: {
|
||||
database,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const updateDNSUri = '/api/v1/edit/dns/index.php';
|
||||
const addDnsApiUri = '/api/v1/add/dns/index.php';
|
||||
const dNSInfoUri = '/api/v1/edit/dns/index.php';
|
||||
const BASE_URL = window.location.origin;
|
||||
const dnsApiUri = '/api/v1/list/dns/index.php';
|
||||
|
||||
export const getDnsList = () => {
|
||||
return axios.get(BASE_URL + dnsApiUri);
|
||||
}
|
||||
|
||||
export const getDNSRecordsList = domain => {
|
||||
return axios.get(`${BASE_URL}${dnsApiUri}?domain=${domain}`);
|
||||
}
|
||||
|
||||
export const getDNSRecordInfo = (domain, recordId) => {
|
||||
return axios.get(`${BASE_URL}${updateDNSUri}?domain=${domain}&record_id=${recordId}`);
|
||||
}
|
||||
|
||||
export const bulkDomainAction = (action, domains) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
domains.forEach(record => {
|
||||
formData.append("domain[]", record);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/dns/', formData);
|
||||
};
|
||||
|
||||
export const bulkAction = (action, records, domain) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
formData.append("domain", domain);
|
||||
|
||||
records.forEach(record => {
|
||||
formData.append("record[]", record);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/dns/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addDomainNameSystem = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addDnsApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const addDomainNameSystemRecord = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addDnsApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getDNSInfo = domain => {
|
||||
return axios.get(BASE_URL + dNSInfoUri, {
|
||||
params: {
|
||||
domain,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateDNS = (data, domain, recordId) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateDNSUri, formDataObject, {
|
||||
params: {
|
||||
domain,
|
||||
record_id: recordId,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
import axios from "axios";
|
||||
let addFavoriteUri = '/api/v1/add/favorite/index.php';
|
||||
let deleteFavoriteUri = '/api/v1/delete/favorite/index.php';
|
||||
let BASE_URL = window.location.origin;
|
||||
|
||||
|
||||
export const addFavorite = (unitId, section) => {
|
||||
return axios.get(BASE_URL + addFavoriteUri, {
|
||||
params: {
|
||||
'v_unit_id': unitId,
|
||||
'v_section': section
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const deleteFavorite = (unitId, section) => {
|
||||
return axios.get(BASE_URL + deleteFavoriteUri, {
|
||||
params: {
|
||||
'v_unit_id': unitId,
|
||||
'v_section': section
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
import axios from 'axios';
|
||||
import { getAuthToken } from 'src/utils/token';
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const usersUri = '/api/v1/list/firewall/index.php';
|
||||
const addFirewallUri = '/api/v1/add/firewall/index.php';
|
||||
const firewallInfoUri = '/api/v1/edit/firewall/index.php';
|
||||
const updateFirewallUri = '/api/v1/edit/firewall/index.php';
|
||||
const addBanIpsUri = '/api/v1/add/firewall/banlist/index.php';
|
||||
const banListUri = '/api/v1/list/firewall/banlist/index.php';
|
||||
|
||||
export const getFirewallList = () => {
|
||||
return axios.get(BASE_URL + usersUri);
|
||||
}
|
||||
|
||||
export const getBanList = () => {
|
||||
return axios.get(BASE_URL + banListUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, ips, banIps) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
ips.forEach(ip => {
|
||||
const banIp = banIps.find(banIp => banIp.NAME === ip);
|
||||
formData.append("ipchain[]", `${ip}:${banIp['CHAIN']}`);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/firewall/banlist/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getBanIps = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.get(BASE_URL + addBanIpsUri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addBanIp = (data) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
formDataObject.append('token', getAuthToken());
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addBanIpsUri, formDataObject, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addFirewall = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addFirewallUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getFirewallInfo = rule => {
|
||||
return axios.get(BASE_URL + firewallInfoUri, {
|
||||
params: {
|
||||
rule,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateFirewall = (data, rule) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateFirewallUri, formDataObject, {
|
||||
params: {
|
||||
rule,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
export const generatorOptions = i18n => {
|
||||
return {
|
||||
minutesRunCommandsOptions: [
|
||||
{ name: i18n['every minute'] ?? 'every minute', value: '*' },
|
||||
{ name: i18n['every two minutes'] ?? 'every two minutes', value: '*/2' },
|
||||
{ name: `${i18n.every || 'every'} 5`, value: '*/5' },
|
||||
{ name: `${i18n.every || 'every'} 10`, value: '*/10' },
|
||||
{ name: `${i18n.every || 'every'} 15`, value: '*/15' },
|
||||
{ name: `${i18n.every || 'every'} 30`, value: '*/30' }
|
||||
],
|
||||
hoursRunCommandsOptions: [
|
||||
{ name: i18n['every hour'] ?? 'every hour', value: '*' },
|
||||
{ name: i18n['every two hours'] ?? 'every two hours', value: '*/2' },
|
||||
{ name: `${i18n.every || 'every'} 6`, value: '*/6' },
|
||||
{ name: `${i18n.every || 'every'} 12`, value: '*/12' }
|
||||
],
|
||||
daysRunCommandsOptions: [
|
||||
{ name: i18n['every day'] ?? 'every day', value: '*' },
|
||||
{ name: i18n['every odd day'] ?? 'every odd day', value: '1-31/2' },
|
||||
{ name: i18n['every even day'] ?? 'every even day', value: '*/2' },
|
||||
{ name: `${i18n.every || 'every'} 3`, value: '*/3' },
|
||||
{ name: `${i18n.every || 'every'} 5`, value: '*/5' },
|
||||
{ name: `${i18n.every || 'every'} 10`, value: '*/10' },
|
||||
{ name: `${i18n.every || 'every'} 15`, value: '*/15' }
|
||||
],
|
||||
hoursOptions: [
|
||||
{ name: '00', value: '0' },
|
||||
{ name: '01', value: '1' },
|
||||
{ name: '02', value: '2' },
|
||||
{ name: '03', value: '3' },
|
||||
{ name: '04', value: '4' },
|
||||
{ name: '05', value: '5' },
|
||||
{ name: '06', value: '6' },
|
||||
{ name: '07', value: '7' },
|
||||
{ name: '08', value: '8' },
|
||||
{ name: '09', value: '9' },
|
||||
{ name: '10', value: '10' },
|
||||
{ name: '11', value: '11' },
|
||||
{ name: '12', value: '12' },
|
||||
{ name: '13', value: '13' },
|
||||
{ name: '14', value: '14' },
|
||||
{ name: '15', value: '15' },
|
||||
{ name: '16', value: '16' },
|
||||
{ name: '17', value: '17' },
|
||||
{ name: '18', value: '18' },
|
||||
{ name: '19', value: '19' },
|
||||
{ name: '20', value: '20' },
|
||||
{ name: '21', value: '21' },
|
||||
{ name: '22', value: '22' },
|
||||
{ name: '23', value: '23' }
|
||||
],
|
||||
hourlyMinutesOptions: [
|
||||
{ name: '00', value: '0' },
|
||||
{ name: '15', value: '15' },
|
||||
{ name: '30', value: '30' },
|
||||
{ name: '45', value: '45' }
|
||||
],
|
||||
dailyMinutesOptions: [
|
||||
{ name: '00', value: '0' },
|
||||
{ name: '01', value: '1' },
|
||||
{ name: '02', value: '2' },
|
||||
{ name: '05', value: '5' },
|
||||
{ name: '10', value: '10' },
|
||||
{ name: '15', value: '15' },
|
||||
{ name: '20', value: '20' },
|
||||
{ name: '25', value: '25' },
|
||||
{ name: '30', value: '30' },
|
||||
{ name: '35', value: '35' },
|
||||
{ name: '40', value: '40' },
|
||||
{ name: '45', value: '45' },
|
||||
{ name: '50', value: '50' },
|
||||
{ name: '55', value: '55' }
|
||||
],
|
||||
weeklyRunCommandOptions: [
|
||||
{ name: i18n['every day'] ?? 'every day', value: '*' },
|
||||
{ name: i18n['weekdays (5 days)'] ?? 'weekdays (5 days)', value: '1,2,3,4,5' },
|
||||
{ name: i18n['weekend (2 days)'] ?? 'weekend (2 days)', value: '0,6' },
|
||||
{ name: i18n.Monday ?? 'Monday', value: '1' },
|
||||
{ name: i18n.Tuesday ?? 'Tuesday', value: '2' },
|
||||
{ name: i18n.Wednesday ?? 'Wednesday', value: '3' },
|
||||
{ name: i18n.Thursday ?? 'Thursday', value: '4' },
|
||||
{ name: i18n.Friday ?? 'Friday', value: '5' },
|
||||
{ name: i18n.Saturday ?? 'Saturday', value: '6' },
|
||||
{ name: i18n.Sunday ?? 'Sunday', value: '0' }
|
||||
],
|
||||
monthlyRunCommandOptions: [
|
||||
{ name: i18n['every month'] ?? 'every month', value: '*' },
|
||||
{ name: i18n['every odd month'] ?? 'every odd month', value: '1-11/2' },
|
||||
{ name: i18n['every even month'] ?? 'every even month', value: '*/2' },
|
||||
{ name: `${i18n.every || 'every'} 3`, value: '*/3' },
|
||||
{ name: `${i18n.every || 'every'} 6`, value: '*/6' },
|
||||
{ name: i18n.Jan ?? 'Jan', value: '1' },
|
||||
{ name: i18n.Feb ?? 'Feb', value: '2' },
|
||||
{ name: i18n.Mar ?? 'Mar', value: '3' },
|
||||
{ name: i18n.Apr ?? 'Apr', value: '4' },
|
||||
{ name: i18n.May ?? 'May', value: '5' },
|
||||
{ name: i18n.Jun ?? 'Jun', value: '6' },
|
||||
{ name: i18n.Jul ?? 'Jul', value: '7' },
|
||||
{ name: i18n.Aug ?? 'Aug', value: '8' },
|
||||
{ name: i18n.Sep ?? 'Sep', value: '9' },
|
||||
{ name: i18n.Oct ?? 'Oct', value: '10' },
|
||||
{ name: i18n.Nov ?? 'Nov', value: '11' },
|
||||
{ name: i18n.Dec ?? 'Dec', value: '12' }
|
||||
],
|
||||
dateOptions: [
|
||||
{ name: '1', value: '1' },
|
||||
{ name: '2', value: '2' },
|
||||
{ name: '3', value: '3' },
|
||||
{ name: '4', value: '4' },
|
||||
{ name: '5', value: '5' },
|
||||
{ name: '6', value: '6' },
|
||||
{ name: '7', value: '7' },
|
||||
{ name: '8', value: '8' },
|
||||
{ name: '9', value: '9' },
|
||||
{ name: '10', value: '10' },
|
||||
{ name: '11', value: '11' },
|
||||
{ name: '12', value: '12' },
|
||||
{ name: '13', value: '13' },
|
||||
{ name: '14', value: '14' },
|
||||
{ name: '15', value: '15' },
|
||||
{ name: '16', value: '16' },
|
||||
{ name: '17', value: '17' },
|
||||
{ name: '18', value: '18' },
|
||||
{ name: '19', value: '19' },
|
||||
{ name: '20', value: '20' },
|
||||
{ name: '21', value: '21' },
|
||||
{ name: '22', value: '22' },
|
||||
{ name: '23', value: '23' },
|
||||
{ name: '24', value: '24' },
|
||||
{ name: '25', value: '25' },
|
||||
{ name: '26', value: '26' },
|
||||
{ name: '27', value: '27' },
|
||||
{ name: '28', value: '28' },
|
||||
{ name: '29', value: '29' },
|
||||
{ name: '30', value: '30' },
|
||||
{ name: '31', value: '31' }
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/ip/index.php';
|
||||
const addIpApiUri = '/api/v1/add/ip/index.php';
|
||||
const additionalInfoUri = '/api/v1/add/ip/index.php';
|
||||
const ipInfoUri = '/api/v1/edit/ip/index.php';
|
||||
const updateIpUri = '/api/v1/edit/ip/index.php';
|
||||
|
||||
export const getIpList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, internetProtocols) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
internetProtocols.forEach(internetProtocol => {
|
||||
formData.append("ip[]", internetProtocol);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/ip/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getAdditionalInfo = () => {
|
||||
return axios.get(BASE_URL + additionalInfoUri);
|
||||
}
|
||||
|
||||
export const addInternetProtocol = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addIpApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getInternetProtocolInfo = ip => {
|
||||
return axios.get(BASE_URL + ipInfoUri, {
|
||||
params: {
|
||||
ip,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateInternetProtocol = (data, ip) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateIpUri, formDataObject, {
|
||||
params: {
|
||||
ip,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const webApiUri = '/api/v1/languages.php';
|
||||
const BASE_URL = window.location.origin;
|
||||
|
||||
export const getLanguages = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const languagesMock = [
|
||||
"ar",
|
||||
"az",
|
||||
"bg",
|
||||
"bs",
|
||||
"cn",
|
||||
"cz",
|
||||
"da",
|
||||
"de",
|
||||
"el",
|
||||
"en",
|
||||
"es",
|
||||
"fa",
|
||||
"fi",
|
||||
"fr",
|
||||
"hu",
|
||||
"id",
|
||||
"it",
|
||||
"ja",
|
||||
"ka",
|
||||
"ko",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt",
|
||||
"ro",
|
||||
"ru",
|
||||
"se",
|
||||
"sr",
|
||||
"th",
|
||||
"tr",
|
||||
"tw",
|
||||
"ua",
|
||||
"ur",
|
||||
"vi"
|
||||
];
|
|
@ -1,8 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/log/index.php';
|
||||
|
||||
export const getLogsList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/mail/index.php';
|
||||
const addMailApiUri = '/api/v1/add/mail/index.php';
|
||||
const mailInfoUri = '/api/v1/edit/mail/index.php';
|
||||
const updateMailUri = '/api/v1/edit/mail/index.php';
|
||||
|
||||
export const getMailList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const getMailAccountList = domain => {
|
||||
return axios.get(`${BASE_URL}${webApiUri}?domain=${domain}`)
|
||||
}
|
||||
|
||||
export const getMailAccountInfo = (domain, account) => {
|
||||
return axios.get(`${BASE_URL}${mailInfoUri}?domain=${domain}&account=${account}`)
|
||||
}
|
||||
|
||||
export const bulkAction = (action, domainNameSystems) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
domainNameSystems.forEach(domainNameSystem => {
|
||||
formData.append("domain[]", domainNameSystem);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/mail/', formData);
|
||||
};
|
||||
|
||||
export const bulkMailAccountAction = (action, domain, accounts = []) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
formData.append("domain", domain);
|
||||
|
||||
accounts.forEach(account => {
|
||||
formData.append("account[]", account);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/mail/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addMail = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addMailApiUri, formDataObject);
|
||||
}
|
||||
|
||||
export const addMailAccount = (data, domain) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(`${BASE_URL}${addMailApiUri}?domain=${domain}`, formDataObject);
|
||||
}
|
||||
|
||||
export const editMailAccount = (data, domain, account) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(`${BASE_URL}${updateMailUri}?domain=${domain}&account=${account}`, formDataObject);
|
||||
}
|
||||
|
||||
export const getMailInfo = domain => {
|
||||
return axios.get(BASE_URL + mailInfoUri, {
|
||||
params: {
|
||||
domain,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateMail = (data, domain) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateMailUri, formDataObject, {
|
||||
params: {
|
||||
domain,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const mailInfoBlockSelectOptions = i18n => [
|
||||
{
|
||||
value: i18n['Use server hostname'],
|
||||
type: 'hostname',
|
||||
},
|
||||
{
|
||||
value: i18n['Use domain hostname'],
|
||||
type: 'domain',
|
||||
},
|
||||
{
|
||||
value: i18n['Use STARTTLS'],
|
||||
type: 'starttls',
|
||||
},
|
||||
{
|
||||
value: i18n['Use SSL / TLS'],
|
||||
type: 'ssl',
|
||||
},
|
||||
{
|
||||
value: i18n['No encryption'],
|
||||
type: 'no_encryption',
|
||||
}
|
||||
];
|
|
@ -1,24 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
let BASE_URL = window.location.origin;
|
||||
let getNotificationsUri = '/api/v1/list/notifications/index.php';
|
||||
let deleteNotificationsUri = '/api/v1/delete/notification/index.php';
|
||||
|
||||
export const getAppNotifications = () => {
|
||||
return axios.get(BASE_URL + getNotificationsUri, {
|
||||
params: {
|
||||
ajax: 1,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const deleteNotification = id => {
|
||||
return axios.get(BASE_URL + deleteNotificationsUri, {
|
||||
params: {
|
||||
'delete': 1,
|
||||
'notification_id': id,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/package/index.php';
|
||||
const additionalPackageInfoUri = '/api/v1/add/package/index.php';
|
||||
const addPackageUri = '/api/v1/add/package/index.php';
|
||||
const packageInfoUri = '/api/v1/edit/package/index.php';
|
||||
const updatePackageUri = '/api/v1/edit/package/index.php';
|
||||
|
||||
export const getPackageList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, backups) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
backups.forEach(backup => {
|
||||
formData.append("package[]", backup);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/package/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addPackage = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addPackageUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getAdditionalPackageInfo = () => {
|
||||
return axios.get(BASE_URL + additionalPackageInfoUri);
|
||||
}
|
||||
|
||||
export const getPackageInfo = item => {
|
||||
return axios.get(BASE_URL + packageInfoUri, {
|
||||
params: {
|
||||
package: item,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updatePackage = (data, item) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updatePackageUri, formDataObject, {
|
||||
params: {
|
||||
package: item
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/rrd/index.php';
|
||||
|
||||
export const getRrdList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export function generateImagePath(period, type, rrd) {
|
||||
return `/api/v1/list/rrd/image.php?/rrd/${type}/${period}-${rrd}.png`;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const resetPasswordUri = '/api/v1/reset/index.php';
|
||||
|
||||
export const resetPassword = (user = '', code = '', password = '', confirmPassword = '') => {
|
||||
const formData = new FormData();
|
||||
|
||||
if (password) {
|
||||
formData.append('password', password);
|
||||
}
|
||||
|
||||
if (confirmPassword) {
|
||||
formData.append('password_confirm', confirmPassword);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
formData.append('user', user);
|
||||
}
|
||||
|
||||
if (code) {
|
||||
formData.append('code', code);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + resetPasswordUri, formData);
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/search/';
|
||||
|
||||
export const getSearchResultsList = term => {
|
||||
return axios.get(BASE_URL + webApiUri + '?q=' + term);
|
||||
}
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
export const values = (select = {}) => {
|
||||
return {
|
||||
usersList: [
|
||||
{ value: 'rebuild', name: select.rebuild },
|
||||
{ value: 'rebuild web', name: select['rebuild web'] },
|
||||
{ value: 'rebuild dns', name: select['rebuild dns'] },
|
||||
{ value: 'rebuild mail', name: select['rebuild mail'] },
|
||||
{ value: 'rebuild db', name: select['rebuild db'] },
|
||||
{ value: 'rebuild cron', name: select['rebuild cron'] },
|
||||
{ value: 'update counters', name: select['update counters'] },
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
webList: [
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
dnsList: [
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
mailList: [
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
dbList: [
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
cronList: [
|
||||
{ value: 'add-cron-reports', name: select['turn on notifications'] },
|
||||
{ value: 'delete-cron-reports', name: select['turn off notifications'] },
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
backupList: [
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
packagesList: [
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
internetProtocolsList: [
|
||||
{ value: 'reread IP', name: select['reread IP'] },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
updatesList: [
|
||||
{ value: 'update', name: select.update }
|
||||
],
|
||||
firewallList: [
|
||||
{ value: 'suspend', name: select.suspend },
|
||||
{ value: 'unsuspend', name: select.unsuspend },
|
||||
{ value: 'delete', name: select.delete }
|
||||
],
|
||||
serverList: [
|
||||
{ value: 'stop', name: select.stop },
|
||||
{ value: 'start', name: select.start },
|
||||
{ value: 'restart', name: select.restart }
|
||||
],
|
||||
backupDetailList: [
|
||||
{ value: 'restore', name: select.restore }
|
||||
],
|
||||
banList: [
|
||||
{ value: 'delete', name: select.delete }
|
||||
]
|
||||
}
|
||||
};
|
|
@ -1,80 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/server/index.php';
|
||||
const serverAdditionalInfoUri = '/api/v1/edit/server/index.php';
|
||||
|
||||
export const getServersList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, services) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
services.forEach(service => {
|
||||
formData.append("service[]", service);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/service/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getServerAdditionalInfo = () => {
|
||||
return axios.get(BASE_URL + serverAdditionalInfoUri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateService = (data, uri = '') => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + `/api/v1/edit/server/${uri}/index.php`, formDataObject, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getServiceInfo = service => {
|
||||
return axios.get(`${BASE_URL}/api/v1/edit/server/${service}/index.php`);
|
||||
}
|
||||
|
||||
export const getServiceLogs = service => {
|
||||
return axios.get(`${BASE_URL}${webApiUri}?${service}`);
|
||||
}
|
||||
|
||||
export const services = [
|
||||
'apache2',
|
||||
'clamd',
|
||||
'cron',
|
||||
'crond',
|
||||
'exim',
|
||||
'exim4',
|
||||
'fail2ban',
|
||||
'iptables',
|
||||
'mariadb',
|
||||
'mysqld',
|
||||
'named',
|
||||
'php-fpm',
|
||||
'php5-fpm',
|
||||
'proftpd',
|
||||
'spamassassin',
|
||||
'spamd',
|
||||
'vsftpd',
|
||||
];
|
|
@ -1,8 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const webApiUri = '/api/v1/list/stats/index.php';
|
||||
|
||||
export const getStatisticsList = user => {
|
||||
return axios.get(BASE_URL + webApiUri + '?user=' + user);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const deleteAutoUpdateUri = '/api/v1/delete/cron/autoupdate/';
|
||||
const addAutoUpdateUri = '/api/v1/add/cron/autoupdate/';
|
||||
const webApiUri = '/api/v1/list/updates/index.php';
|
||||
const BASE_URL = window.location.origin;
|
||||
|
||||
export const getUpdatesList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, updates) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
updates.forEach(update => {
|
||||
formData.append("pkg[]", update);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/vesta/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const enableAutoUpdate = () => {
|
||||
return axios.get(`${BASE_URL}${addAutoUpdateUri}`, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const disableAutoUpdate = () => {
|
||||
return axios.get(`${BASE_URL}${deleteAutoUpdateUri}`, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const userNSApiUri = '/api/v1/list-user-ns.php';
|
||||
|
||||
export const getUserNS = () => {
|
||||
return axios.get(BASE_URL + userNSApiUri);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
import axios from 'axios';
|
||||
import { getAuthToken } from 'src/utils/token';
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const usersUri = '/api/v1/list/user/index.php';
|
||||
const addUsersUri = '/api/v1/add/user/index.php';
|
||||
const userInfoUri = '/api/v1/edit/user/index.php';
|
||||
const updateUserUri = '/api/v1/edit/user/index.php';
|
||||
|
||||
export const getUsersList = () => {
|
||||
return axios.get(BASE_URL + usersUri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const bulkAction = (action, selectedUsers) => {
|
||||
const formData = new FormData();
|
||||
formData.append("token", getAuthToken());
|
||||
formData.append("action", action);
|
||||
|
||||
selectedUsers.forEach(user => {
|
||||
formData.append("user[]", user);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/user/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addUser = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
formDataObject.append("token", getAuthToken());
|
||||
formDataObject.append("ok", "Add");
|
||||
|
||||
return axios.post(BASE_URL + addUsersUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getUserInfo = username => {
|
||||
return axios.get(BASE_URL + userInfoUri, {
|
||||
params: {
|
||||
user: username,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateUser = (data, user) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateUserUri, formDataObject, {
|
||||
params: {
|
||||
user,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { getAuthToken } from "src/utils/token";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const addWebUri = '/api/v1/add/web/index.php';
|
||||
const webApiUri = '/api/v1/list/web/index.php';
|
||||
const webStatsUri = '/api/v1/web-stats.php';
|
||||
const domainInfoUri = '/api/v1/edit/web/index.php';
|
||||
const updateDomainUri = '/api/v1/edit/web/index.php';
|
||||
|
||||
export const getWebList = () => {
|
||||
return axios.get(BASE_URL + webApiUri);
|
||||
}
|
||||
|
||||
export const bulkAction = (action, webDomains) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
webDomains.forEach(webDomain => {
|
||||
formData.append("domain[]", webDomain);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/web/', formData);
|
||||
};
|
||||
|
||||
export const handleAction = uri => {
|
||||
return axios.get(BASE_URL + uri, {
|
||||
params: {
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const addWeb = data => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + addWebUri, formDataObject);
|
||||
}
|
||||
|
||||
export const getWebStats = () => {
|
||||
return axios.get(BASE_URL + webStatsUri);
|
||||
}
|
||||
|
||||
export const getDomainInfo = domain => {
|
||||
return axios.get(BASE_URL + domainInfoUri, {
|
||||
params: {
|
||||
domain,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const updateWebDomain = (data, domain) => {
|
||||
let formDataObject = new FormData();
|
||||
|
||||
for (let key in data) {
|
||||
formDataObject.append(key, data[key]);
|
||||
}
|
||||
|
||||
return axios.post(BASE_URL + updateDomainUri, formDataObject, {
|
||||
params: {
|
||||
domain,
|
||||
token: getAuthToken()
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
|
||||
export const getWebLogs = uri => {
|
||||
return axios.get(BASE_URL + '/api/v1' +uri);
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
import axios from "axios";
|
||||
import QueryString from "qs";
|
||||
const server = window.location.origin + "/file_manager/fm_api.php?";
|
||||
|
||||
export function validateAction(url) {
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
export function cacheData(currentUser, history, rootDir) {
|
||||
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
|
||||
|
||||
if (parsedQueryString.path) {
|
||||
localStorage.setItem("activeWindow", "left");
|
||||
localStorage.setItem("leftListPath", parsedQueryString.path);
|
||||
localStorage.setItem("rightListPath", parsedQueryString.path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (localStorage.getItem("lastUser") === null || currentUser !== localStorage.getItem("lastUser")) {
|
||||
localStorage.setItem("lastUser", currentUser);
|
||||
localStorage.setItem("activeWindow", "left");
|
||||
localStorage.setItem("leftListPath", rootDir);
|
||||
localStorage.setItem("rightListPath", rootDir);
|
||||
return;
|
||||
}
|
||||
|
||||
if (localStorage.getItem("activeWindow") === null || localStorage.getItem("leftListPath") === null || localStorage.getItem("rightListPath") === null) {
|
||||
let path = history.location.search.substring(6).split('/');
|
||||
localStorage.setItem("activeWindow", "left");
|
||||
localStorage.setItem("leftListPath", path);
|
||||
localStorage.setItem("rightListPath", rootDir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export function changeDirectoryOnLoading(server, list) {
|
||||
return axios.get(`${server}dir=${encodePath(localStorage.getItem(list))}&action=cd`);
|
||||
}
|
||||
|
||||
export function changeDirectory(server, path) {
|
||||
return axios.get(`${server}dir=${encodePath(path)}&action=cd`);
|
||||
}
|
||||
|
||||
export function getData(path) {
|
||||
return axios.get(`${server}dir=%2F${path}&action=cd`);
|
||||
}
|
||||
|
||||
export function checkExistingFileName(selectedFiles, activeWindow, leftListData, rightListData) {
|
||||
let selectedFileNames = [];
|
||||
let existingFileNames = [];
|
||||
let newFiles = [];
|
||||
|
||||
for (let i = 0; i < selectedFiles.length; i++) {
|
||||
selectedFileNames.push(selectedFiles[i]);
|
||||
}
|
||||
|
||||
if (activeWindow === "left") {
|
||||
for (let i = 0; i < selectedFileNames.length; i++) {
|
||||
if (leftListData.map((item) => { return item.name }).includes(selectedFileNames[i].name)) {
|
||||
existingFileNames.push(selectedFileNames[i]);
|
||||
} else {
|
||||
newFiles.push(selectedFileNames[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < selectedFileNames.length; i++) {
|
||||
if (rightListData.map((item) => { return item.name }).includes(selectedFileNames[i].name)) {
|
||||
existingFileNames.push(selectedFileNames[i]);
|
||||
} else {
|
||||
newFiles.push(selectedFileNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { existingFileNames, newFiles };
|
||||
}
|
||||
|
||||
export function encodePath(path) {
|
||||
let splitPath = path.split('/');
|
||||
let encodedPath = splitPath.join('%2F');
|
||||
return encodedPath;
|
||||
}
|
||||
|
||||
export function activeWindowPath() {
|
||||
if (localStorage.getItem("activeWindow") === "left") {
|
||||
let currentPath = localStorage.getItem("leftListPath");
|
||||
return currentPath;
|
||||
} else if (localStorage.getItem("activeWindow") === "right") {
|
||||
let currentPath = localStorage.getItem("rightListPath");
|
||||
return currentPath;
|
||||
}
|
||||
}
|
||||
|
||||
export function deleteItems(url, path, selection) {
|
||||
if (!selection.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const promisesArray = selection.map(item =>
|
||||
validateAction(`${url}item=${path}%2F${item}&dir=${path}&action=delete_files`)
|
||||
.then(() => { })
|
||||
);
|
||||
|
||||
return Promise.all(promisesArray);
|
||||
}
|
||||
|
||||
export function moveItems(url, path, targetPath, selection) {
|
||||
if (!selection.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const promisesArray = selection.map(item =>
|
||||
validateAction(`${url}item=${path}%2F${item}&target_name=${targetPath}&action=move_file`)
|
||||
.then(() => { })
|
||||
);
|
||||
|
||||
return Promise.all(promisesArray);
|
||||
}
|
||||
|
||||
export function copyItems(url, path, targetPath, selection) {
|
||||
if (!selection.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const promisesArray = selection.map(item =>
|
||||
validateAction(`${url}item=${path}%2F${item}&filename=${item}&dir=${path}&dir_target=${targetPath}&action=copy_file`)
|
||||
.then(() => { })
|
||||
);
|
||||
|
||||
return Promise.all(promisesArray);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { ADD_CPANEL_FOCUSED_ELEMENT, REMOVE_CPANEL_FOCUSED_ELEMENT } from './controlPanelContentTypes';
|
||||
|
||||
export const addControlPanelContentFocusedElement = value => {
|
||||
return {
|
||||
type: ADD_CPANEL_FOCUSED_ELEMENT,
|
||||
value
|
||||
};
|
||||
};
|
||||
|
||||
export const removeControlPanelContentFocusedElement = () => {
|
||||
return {
|
||||
type: REMOVE_CPANEL_FOCUSED_ELEMENT,
|
||||
value: ''
|
||||
};
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
export const ADD_CPANEL_FOCUSED_ELEMENT = 'ADD_CPANEL_FOCUSED_ELEMENT';
|
||||
export const REMOVE_CPANEL_FOCUSED_ELEMENT = 'REMOVE_CPANEL_FOCUSED_ELEMENT';
|
|
@ -1,29 +0,0 @@
|
|||
import { ADD_FOCUSED_ELEMENT, ADD_ACTIVE_ELEMENT, REMOVE_FOCUSED_ELEMENT, REMOVE_ACTIVE_ELEMENT } from './mainNavigationTypes';
|
||||
|
||||
export const addFocusedElement = value => {
|
||||
return {
|
||||
type: ADD_FOCUSED_ELEMENT,
|
||||
value
|
||||
};
|
||||
};
|
||||
|
||||
export const removeFocusedElement = () => {
|
||||
return {
|
||||
type: REMOVE_FOCUSED_ELEMENT,
|
||||
value: ''
|
||||
};
|
||||
};
|
||||
|
||||
export const addActiveElement = value => {
|
||||
return {
|
||||
type: ADD_ACTIVE_ELEMENT,
|
||||
value
|
||||
};
|
||||
};
|
||||
|
||||
export const removeActiveElement = () => {
|
||||
return {
|
||||
type: REMOVE_ACTIVE_ELEMENT,
|
||||
value: ''
|
||||
};
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
export const ADD_FOCUSED_ELEMENT = 'ADD_FOCUSED_ELEMENT';
|
||||
export const REMOVE_FOCUSED_ELEMENT = 'REMOVE_FOCUSED_ELEMENT';
|
||||
export const ADD_ACTIVE_ELEMENT = 'ADD_ACTIVE_ELEMENT';
|
||||
export const REMOVE_ACTIVE_ELEMENT = 'REMOVE_ACTIVE_ELEMENT';
|
|
@ -1,27 +0,0 @@
|
|||
import { REFRESH_COUNTERS } from './menuCounterTypes';
|
||||
import { checkAuth } from 'src/services/session';
|
||||
import { setAuthToken } from 'src/utils/token';
|
||||
|
||||
export const refreshCounters = () => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
checkAuth()
|
||||
.then(res => {
|
||||
const { data, token } = res.data;
|
||||
|
||||
if (token) setAuthToken(token);
|
||||
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: data
|
||||
}
|
||||
});
|
||||
|
||||
resolve(token);
|
||||
})
|
||||
.catch(err => {
|
||||
reject();
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export const REFRESH_COUNTERS = 'REFRESH_COUNTERS';
|
|
@ -1,15 +0,0 @@
|
|||
import { ADD_NOTIFICATIONS, REMOVE_NOTIFICATIONS } from './notificationTypes';
|
||||
|
||||
export const addNotifications = value => {
|
||||
return {
|
||||
type: ADD_NOTIFICATIONS,
|
||||
value
|
||||
};
|
||||
};
|
||||
|
||||
export const removeNotifications = () => {
|
||||
return {
|
||||
type: REMOVE_NOTIFICATIONS,
|
||||
value: []
|
||||
};
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
export const ADD_NOTIFICATIONS = 'ADD_NOTIFICATIONS';
|
||||
export const REMOVE_NOTIFICATIONS = 'REMOVE_NOTIFICATIONS';
|
|
@ -1,201 +0,0 @@
|
|||
import { LOGIN, LOGOUT, LOGGED_OUT_AS, CHECK_AUTH, RESET_PASSWORD } from './sessionTypes';
|
||||
import { checkAuth, signIn, signInAs, signOut } from 'src/services/session';
|
||||
import { resetPassword } from 'src/ControlPanelService/ResetPassword';
|
||||
import { resetAuthToken, setAuthToken } from 'src/utils/token';
|
||||
import { REFRESH_COUNTERS } from '../MenuCounters/menuCounterTypes';
|
||||
|
||||
const LOGOUT_RESPONSE = 'logged_out';
|
||||
const LOGOUT_AS_RESPONSE = 'logged_out_as';
|
||||
|
||||
export const login = (user, password) => dispatch => {
|
||||
return new Promise((resolve, reject) => {
|
||||
signIn({ user, password }).then((response) => {
|
||||
const { error, session, token, panel, data, user, i18n } = response.data;
|
||||
|
||||
if (token) setAuthToken(token);
|
||||
|
||||
dispatch({
|
||||
type: LOGIN,
|
||||
value: {
|
||||
token: token || '',
|
||||
panel,
|
||||
session,
|
||||
i18n: i18n || {},
|
||||
userName: user,
|
||||
error
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: data,
|
||||
}
|
||||
});
|
||||
resolve(token);
|
||||
}, (error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const reset = ({ user = '', code = '', password = '', password_confirm = '' }) => dispatch => {
|
||||
return new Promise((resolve, reject) => {
|
||||
resetPassword(user, code, password, password_confirm).then((response) => {
|
||||
const { error, session, token, panel, user } = response.data;
|
||||
|
||||
dispatch({
|
||||
type: RESET_PASSWORD,
|
||||
value: {
|
||||
token,
|
||||
panel,
|
||||
session,
|
||||
userName: user,
|
||||
error
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: {},
|
||||
}
|
||||
});
|
||||
resolve(token);
|
||||
}, (error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const loginAs = username => dispatch => {
|
||||
return new Promise((resolve, reject) => {
|
||||
signInAs(username).then((response) => {
|
||||
const { error, token, session, panel, data, user, i18n } = response.data;
|
||||
if (token) setAuthToken(token);
|
||||
|
||||
dispatch({
|
||||
type: LOGIN,
|
||||
value: {
|
||||
userName: user,
|
||||
i18n,
|
||||
session,
|
||||
panel,
|
||||
token,
|
||||
error
|
||||
}
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: data,
|
||||
}
|
||||
});
|
||||
|
||||
resolve(token);
|
||||
}, (error) => {
|
||||
console.error(error);
|
||||
reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const logout = () => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
signOut().then((response) => {
|
||||
const { logout_response, error, userName, user, i18n, session, panel } = response.data;
|
||||
|
||||
if (logout_response === LOGOUT_RESPONSE) {
|
||||
resetAuthToken();
|
||||
|
||||
dispatch({
|
||||
type: LOGOUT,
|
||||
value: {
|
||||
userName: '',
|
||||
token: '',
|
||||
panel: {},
|
||||
session: {},
|
||||
i18n: [],
|
||||
error,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: {},
|
||||
}
|
||||
});
|
||||
|
||||
resolve();
|
||||
} else if (logout_response === LOGOUT_AS_RESPONSE) {
|
||||
dispatch({
|
||||
type: LOGGED_OUT_AS,
|
||||
value: {
|
||||
userName,
|
||||
session,
|
||||
panel,
|
||||
token: '',
|
||||
i18n,
|
||||
error,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user,
|
||||
}
|
||||
});
|
||||
|
||||
resolve();
|
||||
} else {
|
||||
resolve(`Error while signing out: ${logout_response}`);
|
||||
}
|
||||
}, (error) => {
|
||||
console.error(error);
|
||||
reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const checkAuthHandler = () => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
checkAuth()
|
||||
.then(res => {
|
||||
const { user, data, session, panel, error, i18n, token } = res.data;
|
||||
|
||||
if (token) setAuthToken(token);
|
||||
|
||||
dispatch({
|
||||
type: CHECK_AUTH,
|
||||
value: {
|
||||
userName: user,
|
||||
i18n,
|
||||
session,
|
||||
panel,
|
||||
token,
|
||||
error
|
||||
}
|
||||
});
|
||||
dispatch({
|
||||
type: REFRESH_COUNTERS,
|
||||
value: {
|
||||
user: data,
|
||||
}
|
||||
});
|
||||
|
||||
resolve(token);
|
||||
})
|
||||
.catch(err => {
|
||||
reject();
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const removeToken = () => {
|
||||
return {
|
||||
type: LOGOUT,
|
||||
value: {
|
||||
token: '',
|
||||
error: ''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
export const LOGIN = 'LOGIN';
|
||||
export const LOGOUT = 'LOGOUT';
|
||||
export const LOGIN_AS = 'LOGIN_AS';
|
||||
export const CHECK_AUTH = 'CHECK_AUTH';
|
||||
export const LOGGED_OUT_AS = 'LOGGED_OUT_AS';
|
||||
export const RESET_PASSWORD = 'RESET_PASSWORD';
|
|
@ -1,85 +0,0 @@
|
|||
import React, { } from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import ListItem from '../ControlPanel/ListItem/ListItem';
|
||||
import Container from '../ControlPanel/Container/Container';
|
||||
import { faFileDownload } from '@fortawesome/free-solid-svg-icons'
|
||||
import './Backup.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const Backup = props => {
|
||||
const { data } = props;
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const token = localStorage.getItem("token");
|
||||
|
||||
const toggleFav = (starred) => {
|
||||
if (starred) {
|
||||
props.toggleFav(props.data.NAME, 'add');
|
||||
} else {
|
||||
props.toggleFav(props.data.NAME, 'delete');
|
||||
}
|
||||
}
|
||||
|
||||
const checkItem = () => {
|
||||
props.checkItem(props.data.NAME);
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
props.handleModal(data.delete_conf, `/api/v1/delete/backup/?backup=${data.NAME}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
id={data.NAME}
|
||||
date={data.DATE}
|
||||
toggleFav={toggleFav}
|
||||
checkItem={checkItem}
|
||||
focused={data.FOCUSED}
|
||||
starred={data.STARRED}
|
||||
checked={data.isChecked}>
|
||||
|
||||
<Container className="r-col w-85">
|
||||
<div className="name">{data.NAME}</div>
|
||||
<div className="stats">
|
||||
<Container className="c-1">
|
||||
<div>{i18n['Backup Size']}: <span><span className="stat">{data.SIZE}</span>{i18n.mb}</span></div>
|
||||
</Container>
|
||||
<Container className="c-2">
|
||||
<div>{i18n.Type}: <span className="stat">{data.TYPE}</span></div>
|
||||
</Container>
|
||||
<Container className="c-3">
|
||||
<div>{i18n['Run Time']}: <span className="stat">{data.RUNTIME} minute</span></div>
|
||||
</Container>
|
||||
</div>
|
||||
</Container>
|
||||
<div className="actions">
|
||||
|
||||
{data.UPDATED === 'no' && <div><a href={`/update/vesta/?pkg=${data.NAME}`}>{i18n.update} <FontAwesomeIcon icon="wrench" /></a></div>}
|
||||
|
||||
<div>
|
||||
<a className="link-download" href={`/api/v1/download/backup/?backup=${data.NAME}&token=${token}`}>
|
||||
{i18n.download}
|
||||
{data.FOCUSED ? <span className="shortcut-button">D</span> : <FontAwesomeIcon icon={faFileDownload} />}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Link className="link-download" to={`/list/backup?backup=${data.NAME}`}>
|
||||
{i18n['configure restore settings']}
|
||||
{data.FOCUSED ? <span className="shortcut-button html-unicode">↩</span> : <FontAwesomeIcon icon="list" />}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="link-delete" onClick={() => handleDelete()}>
|
||||
{i18n.Delete}
|
||||
{data.FOCUSED ? <span className="shortcut-button del">Del</span> : <FontAwesomeIcon icon="times" />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default Backup;
|
|
@ -1,7 +0,0 @@
|
|||
.backups-wrapper .list-item .c-1 div > span {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.backups-restore-details .list-item .star {
|
||||
display: none;
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { addActiveElement, removeFocusedElement } from "src/actions/MainNavigation/mainNavigationActions";
|
||||
import { updateBackupExclusions, getBackupExclusionsInfo } from 'src/ControlPanelService/Backup';
|
||||
import TextArea from 'src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea';
|
||||
import AddItemLayout from 'src/components/ControlPanel/AddItemLayout/AddItemLayout';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Toolbar from 'src/components/MainNav/Toolbar/Toolbar';
|
||||
import Spinner from 'src/components/Spinner/Spinner';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import './style.scss';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
const EditBackupExclusions = () => {
|
||||
const token = localStorage.getItem("token");
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const [state, setState] = useState({
|
||||
data: {},
|
||||
loading: false,
|
||||
errorMessage: '',
|
||||
okMessage: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(addActiveElement('/list/backup/'));
|
||||
dispatch(removeFocusedElement());
|
||||
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
getBackupExclusionsInfo()
|
||||
.then(response => {
|
||||
setState({
|
||||
...state,
|
||||
data: response.data,
|
||||
errorMessage: response.data['error_msg'],
|
||||
okMessage: response.data['ok_msg'],
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}, []);
|
||||
|
||||
const submitFormHandler = event => {
|
||||
event.preventDefault();
|
||||
let updatedExclusions = {};
|
||||
|
||||
for (var [name, value] of (new FormData(event.target)).entries()) {
|
||||
updatedExclusions[name] = value;
|
||||
}
|
||||
|
||||
updatedExclusions['token'] = token;
|
||||
updatedExclusions['save'] = 'save';
|
||||
|
||||
if (Object.keys(updatedExclusions).length !== 0 && updatedExclusions.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
updateBackupExclusions(updatedExclusions)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
|
||||
|
||||
if (errorMessage) {
|
||||
setState({ ...state, errorMessage, okMessage: '', loading: false });
|
||||
} else if (okMessage) {
|
||||
setState({ ...state, errorMessage: '', okMessage, loading: false });
|
||||
} else {
|
||||
setState({ ...state, loading: false });
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-template edit-backup-exclusions">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.BACKUP}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false}>
|
||||
<div></div>
|
||||
<div className="search-toolbar-name">{i18n['Editing Backup Exclusions']}</div>
|
||||
<div className="error">
|
||||
<span className="error-message">
|
||||
{state.data.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}
|
||||
</span>
|
||||
</div>
|
||||
<div className="success">
|
||||
<span className="ok-message">
|
||||
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<AddItemLayout>
|
||||
{state.loading ? <Spinner /> :
|
||||
<form onSubmit={event => submitFormHandler(event)} id="edit-backup-exclusions">
|
||||
<TextArea
|
||||
title={i18n['Web Domains']}
|
||||
defaultValue={state.data.web}
|
||||
name="v_web"
|
||||
id="v_web" />
|
||||
|
||||
<TextArea
|
||||
title={i18n['Mail Domains']}
|
||||
defaultValue={state.data.mail}
|
||||
name="v_mail"
|
||||
id="v_mail" />
|
||||
|
||||
<TextArea
|
||||
title={i18n['Databases']}
|
||||
defaultValue={state.data.db}
|
||||
name="v_db"
|
||||
id="v_db" />
|
||||
|
||||
<TextArea
|
||||
title={i18n['User Directories']}
|
||||
defaultValue={state.data.userdir}
|
||||
name="v_userdir"
|
||||
id="v_userdir" />
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Save}</button>
|
||||
<button type="button" className="back" onClick={() => history.push('/list/backup/exclusions')}>{i18n.Back}</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
</AddItemLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditBackupExclusions;
|
|
@ -1,3 +0,0 @@
|
|||
.content .edit-backup-exclusions .toolbar .search-toolbar-name {
|
||||
width: auto;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Container from '../../ControlPanel/Container/Container';
|
||||
|
||||
import './style.scss';
|
||||
|
||||
const Exclusion = ({ data, focused }) => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
const renderExclusionItems = () => {
|
||||
if (!Array.isArray(data.ITEMS)) {
|
||||
for (let item in data.ITEMS) {
|
||||
return <><b>{item}</b> {data.ITEMS[item]}<br /></>;
|
||||
}
|
||||
} else {
|
||||
return i18n['no exclusions'];
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={focused ? 'statistic-item focused' : 'statistic-item'} id={data.NAME}>
|
||||
<Container className="l-col w-15" />
|
||||
<Container className="r-col w-85">
|
||||
<div className="stats">
|
||||
<div className="name">{data.NAME}</div>
|
||||
<div className="exclusion-items">{renderExclusionItems()}</div>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Exclusion;
|
|
@ -1,33 +0,0 @@
|
|||
.statistic-item {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
padding: 25px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
.l-col {
|
||||
padding-left: 0;
|
||||
flex-basis: 14.3%;
|
||||
}
|
||||
|
||||
.r-col {
|
||||
flex-basis: 85.7%;
|
||||
|
||||
.stats {
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
font-size: 24px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.exclusion-items {
|
||||
flex-basis: 83.4%;
|
||||
}
|
||||
|
||||
> div {
|
||||
flex: unset;
|
||||
flex-basis: 16.6%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Container from '../../ControlPanel/Container/Container';
|
||||
import ListItem from '../../ControlPanel/ListItem/ListItem';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import './RestoreSetting.scss';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
export default function RestoreSetting({ data, checkItemFunc = () => { }, restoreSetting = () => { } }) {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
const displayBackupDetailName = type => {
|
||||
switch (type) {
|
||||
case 'WEB': return `WEB ${i18n['domain']}`;
|
||||
case 'MAIL': return `MAIL ${i18n['domain']}`;
|
||||
case 'DNS': return `DNS ${i18n['domain']}`;
|
||||
case 'CRON': return i18n['cron'];
|
||||
case 'UDIR': return i18n['user dir'];
|
||||
default: return i18n['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
const checkItem = () => {
|
||||
checkItemFunc(data.NAME);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
date={false}
|
||||
id={data.NAME}
|
||||
focused={data.FOCUSED}
|
||||
checked={data.isChecked}
|
||||
checkItem={checkItem}>
|
||||
|
||||
<Container className="r-col w-85">
|
||||
<div className="stats">
|
||||
<Container className="c-1">
|
||||
<div style={{ textTransform: 'uppercase' }}>{displayBackupDetailName(data.type)}</div>
|
||||
</Container>
|
||||
<Container className="c-2">
|
||||
<b>{data.name}</b>
|
||||
</Container>
|
||||
<Container className="c-3"></Container>
|
||||
<Container className="c-4"></Container>
|
||||
<Container className="c-5"></Container>
|
||||
</div>
|
||||
</Container>
|
||||
<div className="actions">
|
||||
<div>
|
||||
<button className="link-restore" onClick={() => restoreSetting(data.restoreLinkParams)}>
|
||||
{i18n['restore']}
|
||||
{data.FOCUSED ? <span className="shortcut-button">R</span> : <FontAwesomeIcon icon="play" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
$whiteBackground: #ececec;
|
||||
$primary: #2c54ac;
|
||||
$primaryLight: #d7dcef;
|
||||
$primaryActive: #1e5cb2;
|
||||
$secondary: #fcac04;
|
||||
$secondaryLight: #f8b014;
|
||||
$secondaryActive: #fdb51c;
|
||||
$hoverButtonText: #2c54ac;
|
||||
$activeButtonText: #fff;
|
||||
$textColor: #555;
|
||||
|
||||
.backups-restore-settings {
|
||||
.list-item {
|
||||
.r-col {
|
||||
.stats {
|
||||
.c-1 {
|
||||
margin: 12px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
> div {
|
||||
font-weight: bolder;
|
||||
text-transform: uppercase;
|
||||
height: 38px;
|
||||
|
||||
a, button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: $textColor;
|
||||
padding: 10px 15px;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background: $whiteBackground;
|
||||
color: white;
|
||||
|
||||
svg {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
color: $textColor;
|
||||
}
|
||||
}
|
||||
|
||||
.link-restore {
|
||||
svg {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $hoverButtonText;
|
||||
background-color: $primaryLight;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $activeButtonText;
|
||||
background-color: $primaryActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,305 +0,0 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { addControlPanelContentFocusedElement, removeControlPanelContentFocusedElement } from 'src/actions/ControlPanelContent/controlPanelContentActions';
|
||||
import * as MainNavigation from 'src/actions/MainNavigation/mainNavigationActions';
|
||||
import SearchInput from 'src/components/MainNav/Toolbar/SearchInput/SearchInput';
|
||||
import LeftButton from 'src/components/MainNav/Toolbar/LeftButton/LeftButton';
|
||||
import { getBackupDetails, restoreBackupSetting, bulkRestore } from 'src/ControlPanelService/Backup';
|
||||
import Checkbox from 'src/components/MainNav/Toolbar/Checkbox/Checkbox';
|
||||
import Select from 'src/components/MainNav/Toolbar/Select/Select';
|
||||
import Toolbar from 'src/components/MainNav/Toolbar/Toolbar';
|
||||
import RestoreSetting from '../RestoreSetting/RestoreSetting';
|
||||
import Modal from 'src/components/ControlPanel/Modal/Modal';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import Spinner from 'src/components/Spinner/Spinner';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import './BackupRestoreSettings.scss';
|
||||
|
||||
export default function BackupRestoreSettings(props) {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const token = localStorage.getItem("token");
|
||||
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
|
||||
const { focusedElement } = useSelector(state => state.mainNavigation);
|
||||
const dispatch = useDispatch();
|
||||
const [backupDetailsData, setBackupDetailsData] = useState([]);
|
||||
const [modal, setModal] = useState({
|
||||
text: '',
|
||||
visible: false,
|
||||
});
|
||||
const [state, setState] = useState({
|
||||
loading: false,
|
||||
backupDetails: [],
|
||||
toggledAll: false,
|
||||
selection: [],
|
||||
totalAmount: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(removeControlPanelContentFocusedElement());
|
||||
fetchData();
|
||||
|
||||
return () => dispatch(removeControlPanelContentFocusedElement());
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleContentSelection);
|
||||
window.addEventListener("keydown", handleFocusedElementShortcuts);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleContentSelection);
|
||||
window.removeEventListener("keydown", handleFocusedElementShortcuts);
|
||||
};
|
||||
}, [controlPanelFocusedElement, focusedElement, backupDetailsData]);
|
||||
|
||||
const handleContentSelection = event => {
|
||||
if (event.keyCode === 65) {
|
||||
handleRestore(`?backup=${props.backup}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.keyCode === 38 || event.keyCode === 40) {
|
||||
if (focusedElement) {
|
||||
dispatch(MainNavigation.removeFocusedElement());
|
||||
}
|
||||
}
|
||||
|
||||
if (event.keyCode === 38) {
|
||||
event.preventDefault();
|
||||
handleArrowUp();
|
||||
} else if (event.keyCode === 40) {
|
||||
event.preventDefault();
|
||||
handleArrowDown();
|
||||
}
|
||||
}
|
||||
|
||||
const initFocusedElement = backupDetails => {
|
||||
backupDetails[0]['FOCUSED'] = backupDetails[0]['NAME'];
|
||||
setBackupDetailsData(backupDetails);
|
||||
dispatch(addControlPanelContentFocusedElement(backupDetails[0]['NAME']));
|
||||
}
|
||||
|
||||
const handleArrowDown = () => {
|
||||
let backupDetails = [...backupDetailsData];
|
||||
|
||||
if (focusedElement) {
|
||||
MainNavigation.removeFocusedElement();
|
||||
}
|
||||
|
||||
if (controlPanelFocusedElement === '') {
|
||||
initFocusedElement(backupDetails);
|
||||
return;
|
||||
}
|
||||
|
||||
let nextFocusedElement = backupDetails[controlPanelFocusedElement + 1];
|
||||
|
||||
if (nextFocusedElement) {
|
||||
backupDetails[controlPanelFocusedElement]['FOCUSED'] = '';
|
||||
nextFocusedElement['FOCUSED'] = nextFocusedElement['NAME'];
|
||||
document.getElementById(nextFocusedElement['NAME']).scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
setBackupDetailsData(backupDetails);
|
||||
dispatch(addControlPanelContentFocusedElement(nextFocusedElement['NAME']));
|
||||
}
|
||||
}
|
||||
|
||||
const handleArrowUp = () => {
|
||||
let backupDetails = [...backupDetailsData];
|
||||
|
||||
if (focusedElement) {
|
||||
MainNavigation.removeFocusedElement();
|
||||
}
|
||||
|
||||
if (controlPanelFocusedElement === '') {
|
||||
initFocusedElement(backupDetails);
|
||||
return;
|
||||
}
|
||||
|
||||
let nextFocusedElement = backupDetails[controlPanelFocusedElement - 1];
|
||||
|
||||
if (nextFocusedElement) {
|
||||
backupDetails[controlPanelFocusedElement]['FOCUSED'] = '';
|
||||
nextFocusedElement['FOCUSED'] = nextFocusedElement['NAME'];
|
||||
document.getElementById(nextFocusedElement['NAME']).scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
setBackupDetailsData(backupDetails);
|
||||
dispatch(addControlPanelContentFocusedElement(nextFocusedElement['NAME']));
|
||||
}
|
||||
}
|
||||
|
||||
const handleFocusedElementShortcuts = event => {
|
||||
let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus');
|
||||
|
||||
if (controlPanelFocusedElement > 0 || controlPanelFocusedElement !== '' && !isSearchInputFocused) {
|
||||
switch (event.keyCode) {
|
||||
case 82: return handleRestore();
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleRestore = params => {
|
||||
const paramsUri = params ? params : backupDetailsData[controlPanelFocusedElement].restoreLinkParams;
|
||||
|
||||
restoreBackupSetting(paramsUri)
|
||||
.then(response => displayModal(response.data.message))
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
getBackupDetails(props.backup)
|
||||
.then(result => {
|
||||
reformatData(result.data.data[props.backup]);
|
||||
setState({
|
||||
...state,
|
||||
totalAmount: result.data.totalAmount,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
|
||||
const reformatData = data => {
|
||||
let reformattedData = ['WEB', 'DNS', 'MAIL', 'DB', 'UDIR', 'CRON'].reduce((acc, cat) => {
|
||||
data[cat].split(',').map(item => {
|
||||
acc.push({
|
||||
type: cat,
|
||||
name: item,
|
||||
restoreLinkParams: `?backup=${props.backup}&type=${cat.toLowerCase()}&object=${item}`
|
||||
});
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
setBackupDetailsData(reformattedData);
|
||||
}
|
||||
|
||||
const listBackups = () => {
|
||||
const backupDetails = [...backupDetailsData];
|
||||
const result = [];
|
||||
|
||||
backupDetails.forEach((backupDetail, index) => {
|
||||
backupDetail.NAME = index;
|
||||
backupDetail.FOCUSED = controlPanelFocusedElement === index;
|
||||
result.push(backupDetail);
|
||||
});
|
||||
|
||||
return result.map((item, index) => {
|
||||
return <RestoreSetting data={item} key={index} checkItemFunc={name => checkItem(name)} restoreSetting={handleRestore} />;
|
||||
});
|
||||
}
|
||||
|
||||
const checkItem = name => {
|
||||
const { selection } = state;
|
||||
let duplicate = [...selection];
|
||||
let backupDetailsDuplicate = [...backupDetailsData];
|
||||
let checkedItem = duplicate.indexOf(name);
|
||||
|
||||
let incomingItem = backupDetailsDuplicate.findIndex(backupDetail => backupDetail.NAME === name);
|
||||
backupDetailsDuplicate[incomingItem].isChecked = !backupDetailsDuplicate[incomingItem].isChecked;
|
||||
|
||||
if (checkedItem !== -1) {
|
||||
duplicate.splice(backupDetailsDuplicate[name]['name'], 1);
|
||||
} else {
|
||||
duplicate.push(backupDetailsDuplicate[name]['name']);
|
||||
}
|
||||
|
||||
setState({ ...state, selection: duplicate });
|
||||
setBackupDetailsData(backupDetailsDuplicate);
|
||||
}
|
||||
|
||||
const toggleAll = toggled => {
|
||||
const backupDetailsDuplicate = [...backupDetailsData];
|
||||
|
||||
if (toggled) {
|
||||
let backupDetailNames = [];
|
||||
let backupDetails = backupDetailsDuplicate.map(backupDetail => {
|
||||
backupDetailNames.push(backupDetail.name);
|
||||
backupDetail.isChecked = true;
|
||||
return backupDetail;
|
||||
});
|
||||
|
||||
setState({ ...state, selection: backupDetailNames, toggledAll: toggled });
|
||||
setBackupDetailsData(backupDetails);
|
||||
} else {
|
||||
let backupDetails = backupDetailsDuplicate.map(backupDetail => {
|
||||
backupDetail.isChecked = false;
|
||||
return backupDetail;
|
||||
});
|
||||
|
||||
setState({ ...state, selection: [], toggledAll: toggled });
|
||||
setBackupDetailsData(backupDetails);
|
||||
}
|
||||
}
|
||||
|
||||
const bulk = action => {
|
||||
const { selection } = state;
|
||||
|
||||
if (selection.length && action) {
|
||||
setState({ ...state, loading: true });
|
||||
bulkRestore(action, selection, props.backup)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
displayModal(result.data.message);
|
||||
toggleAll(false);
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
const displayModal = text => {
|
||||
setState({ ...state, loading: false });
|
||||
setModal({ ...modal, visible: true, text });
|
||||
}
|
||||
|
||||
const modalCancelHandler = () => {
|
||||
setModal({ ...modal, visible: false, text: '' });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mail-accounts backups-restore-settings">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.BACKUP}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false} >
|
||||
<LeftButton name={i18n['Restore All']} list="backup-details" onClick={() => handleRestore(`?backup=${props.backup}`)} showLeftMenu={true} />
|
||||
<div className="r-menu">
|
||||
<div className="input-group input-group-sm">
|
||||
<Checkbox toggleAll={toggleAll} toggled={state.toggledAll} />
|
||||
<Select list='backupDetailList' bulkAction={bulk} />
|
||||
<SearchInput handleSearchTerm={term => props.changeSearchTerm(term)} />
|
||||
</div>
|
||||
</div>
|
||||
</Toolbar>
|
||||
{state.loading
|
||||
? <Spinner />
|
||||
: (
|
||||
<>
|
||||
<div className="mail-accounts-wrapper">
|
||||
<div className="subtitle">
|
||||
<span>{`${i18n['Listing']} ${props.backup}`}</span>
|
||||
</div>
|
||||
{listBackups()}
|
||||
</div>
|
||||
<div className="footer-actions-wrapper">
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
<div className="back">
|
||||
<Link to="/list/backup/">{i18n['Back']}</Link>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
<Modal
|
||||
onSave={modalCancelHandler}
|
||||
showCancelButton={false}
|
||||
show={modal.visible}
|
||||
text={modal.text} />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
.backups-restore-settings {
|
||||
.toolbar {
|
||||
.backup-details-icon {
|
||||
svg {
|
||||
transform: translateX(2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mail-accounts-wrapper {
|
||||
.list-item {
|
||||
.l-col {
|
||||
.star {
|
||||
.checkbox + div {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
import React from 'react';
|
||||
import Container from '../Container/Container';
|
||||
|
||||
import './AddItemLayout.scss';
|
||||
|
||||
const AddItemLayout = ({ date = '', time = '', status = '', children }) => {
|
||||
const renderDate = () => {
|
||||
if (date.length > 0) {
|
||||
let newDate = new Date(date);
|
||||
let day = newDate.getDate();
|
||||
let month = newDate.getMonth();
|
||||
let year = newDate.getFullYear();
|
||||
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
return <div className="date">{day} {months[month]} {year}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-item">
|
||||
<Container className="l-col w-14">
|
||||
{renderDate()}
|
||||
<div className="time">
|
||||
{time}
|
||||
</div>
|
||||
<div className="status uppercase">
|
||||
{status}
|
||||
</div>
|
||||
</Container>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddItemLayout;
|
|
@ -1,295 +0,0 @@
|
|||
$whiteBackground: #ececec;
|
||||
$primary: #2c54ac;
|
||||
$primaryLight: #d7dcef;
|
||||
$primaryActive: #1e5cb2;
|
||||
$secondary: #fcac04;
|
||||
$secondaryLight: #f8b014;
|
||||
$secondaryActive: #fdb51c;
|
||||
$hoverButtonText: #2c54ac;
|
||||
$activeButtonText: #fff;
|
||||
$textColor: #555;
|
||||
|
||||
$optionalButtonHover: $primary;
|
||||
$optionalButtonActive: $primaryLight;
|
||||
$deleteButtonColorHover: #b00e5b;
|
||||
$deleteButtonColorActive: #b11661;
|
||||
$backButtonBackground: #DFDEDD;
|
||||
$backButtonBackgroundHover: #999;
|
||||
$transition: all 200ms cubic-bezier(0.4, 0.1, 0.5, 0.85);
|
||||
$errorColor: #BE5ABF;
|
||||
|
||||
.content .edit-template {
|
||||
padding-bottom: 2rem;
|
||||
|
||||
.toolbar {
|
||||
justify-content: unset;
|
||||
|
||||
> div {
|
||||
width: 14.3%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.error,
|
||||
div.success {
|
||||
width: max-content !important;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
|
||||
svg {
|
||||
font-size: 13px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
span.error-message {
|
||||
color: $errorColor;
|
||||
|
||||
svg {
|
||||
margin-right: 7px;
|
||||
font-size: 13px;
|
||||
color: $errorColor;
|
||||
}
|
||||
}
|
||||
|
||||
span.ok-message {
|
||||
color: $primary;
|
||||
|
||||
svg {
|
||||
color: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-toolbar-name {
|
||||
padding: 10px 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.edit-item,
|
||||
.login-layout {
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.l-col {
|
||||
margin-right: 1.75%;
|
||||
}
|
||||
|
||||
form {
|
||||
button,
|
||||
a {
|
||||
color:$primary;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: $secondaryLight;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $secondaryActive;
|
||||
}
|
||||
}
|
||||
|
||||
button.optional {
|
||||
&:hover {
|
||||
color: $optionalButtonHover;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $optionalButtonActive;
|
||||
}
|
||||
}
|
||||
|
||||
button.delete {
|
||||
&:hover {
|
||||
color: $deleteButtonColorHover;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $deleteButtonColorActive;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
input[type=text],
|
||||
input[type=password],
|
||||
input[type=email],
|
||||
textarea,
|
||||
select {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
border-radius: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #909090;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
outline: none;
|
||||
border-color: $primaryActive;
|
||||
box-shadow: unset;
|
||||
}
|
||||
}
|
||||
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:focus,
|
||||
input:-webkit-autofill:active {
|
||||
background-color: $primaryLight;
|
||||
border-color: $primaryActive;
|
||||
filter: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
input:autofill,
|
||||
input:autofill:hover,
|
||||
input:autofill:focus,
|
||||
input:autofill:active {
|
||||
background-color: $primaryLight;
|
||||
border-color: $primaryActive;
|
||||
filter: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
button {
|
||||
background: unset;
|
||||
border: none;
|
||||
box-shadow: unset;
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: calc(1.5em + 0.75rem + 6px);
|
||||
border-radius: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #909090;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: unset;
|
||||
border-color: $primaryActive;
|
||||
background: #d7dcef9e;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: $textColor;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label.label-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
width: max-content;
|
||||
|
||||
span {
|
||||
font-weight: normal;
|
||||
text-transform: uppercase;
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
margin: 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
color: $textColor;
|
||||
}
|
||||
|
||||
.buttons-wrapper {
|
||||
margin-top: 2.5rem;
|
||||
|
||||
button {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
margin-right: 10px;
|
||||
padding: .35rem 2.25rem;
|
||||
border-radius: 4px;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
.add {
|
||||
color: $activeButtonText;
|
||||
background: $primary;
|
||||
|
||||
&:hover {
|
||||
color: $hoverButtonText;
|
||||
background: $primaryLight;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $activeButtonText;
|
||||
background: $primaryActive;
|
||||
}
|
||||
}
|
||||
|
||||
.back {
|
||||
color: #777;
|
||||
background: $backButtonBackground;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
background: $backButtonBackgroundHover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-col {
|
||||
padding: 20px 0 0;
|
||||
|
||||
.date,
|
||||
.time {
|
||||
margin: 10px 0 0;
|
||||
color: #777;
|
||||
font-size: 12px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.time {
|
||||
margin: 6px 0 10px;
|
||||
}
|
||||
|
||||
.status {
|
||||
color: $primary;
|
||||
font-size: 11px;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
const Checkbox = ({ name, id, title, defaultChecked = false, onChange = () => { }, checked }) => {
|
||||
const [checkedState, setCheckedState] = useState(defaultChecked);
|
||||
|
||||
useEffect(() => {
|
||||
setCheckedState(checked);
|
||||
}, [checked]);
|
||||
|
||||
const changeCheckbox = event => {
|
||||
setCheckedState(event.target.checked);
|
||||
onChange(event.target.checked);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="form-group">
|
||||
<div className="checkbox-wrapper">
|
||||
<input
|
||||
type="checkbox"
|
||||
name={name}
|
||||
id={id}
|
||||
checked={checkedState}
|
||||
onChange={changeCheckbox}
|
||||
defaultChecked={defaultChecked} />
|
||||
<label htmlFor={id}>{title}</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Checkbox;
|
|
@ -1,79 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const NameServers = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const [state, setState] = useState({
|
||||
nameServersAmount: [],
|
||||
usersNS: []
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (props.usersNS) {
|
||||
let initNameServersAmount = props.usersNS.map((userNS, index) => index + 1);
|
||||
setState({ ...state, usersNS: props.usersNS, nameServersAmount: initNameServersAmount });
|
||||
}
|
||||
}, [props.usersNS]);
|
||||
|
||||
const renderNameServerInputs = () => {
|
||||
return state.nameServersAmount.map((nameServer, index) => {
|
||||
if (nameServer < 9) {
|
||||
return (
|
||||
<div className="name-server-input-wrapper" key={index}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id={`v_ns${index + 1}`}
|
||||
defaultValue={state.usersNS[index] || ''}
|
||||
name={`v_ns${index + 1}`} />
|
||||
<button
|
||||
type="button"
|
||||
className={index < 2 ? 'hide' : 'show delete'}
|
||||
onClick={() => onDeleteNameServer(index)}>
|
||||
{i18n.delete ?? 'Delete'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const addNameServerClassName = () => {
|
||||
return state.nameServersAmount.length === 8 ? 'hide' : 'show optional';
|
||||
}
|
||||
|
||||
const addNameServer = () => {
|
||||
let nameServersLength = state.nameServersAmount.length;
|
||||
let nameServersDuplicate = [...state.nameServersAmount];
|
||||
|
||||
nameServersDuplicate.push(nameServersLength + 1);
|
||||
|
||||
setState({ ...state, nameServersAmount: nameServersDuplicate });
|
||||
}
|
||||
|
||||
const onDeleteNameServer = index => {
|
||||
let nameServersDuplicate = [...state.nameServersAmount];
|
||||
|
||||
nameServersDuplicate.splice(index - 1, 1);
|
||||
|
||||
setState({ ...state, nameServersAmount: nameServersDuplicate });
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="form-group name-servers">
|
||||
<label htmlFor="v_ns1">{i18n['Name servers'] ?? 'Name servers'}</label>
|
||||
{renderNameServerInputs()}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={addNameServerClassName()}
|
||||
onClick={() => addNameServer()}>
|
||||
{i18n['Add one more Name Server'] ?? 'Add one more Name Server'}
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default NameServers;
|
|
@ -1,71 +0,0 @@
|
|||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const Password = ({ defaultValue, onChange = () => { }, id, name, title, showGenerationButton = true, ...props }) => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const [state, setState] = useState({
|
||||
hidePassword: false,
|
||||
generatedPassword: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultValue && !state.generatedPassword) {
|
||||
setState({ ...state, generatedPassword: defaultValue });
|
||||
}
|
||||
}, [defaultValue]);
|
||||
|
||||
const hidePasswordHandler = () => {
|
||||
setState({ ...state, hidePassword: !state.hidePassword });
|
||||
}
|
||||
|
||||
const generatePassword = () => {
|
||||
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
|
||||
let stringLength = 10;
|
||||
let result = '';
|
||||
|
||||
for (var i = 0; i < stringLength; i++) {
|
||||
let randomNumber = Math.floor(Math.random() * chars.length);
|
||||
result += chars.substr(randomNumber, 1);
|
||||
}
|
||||
|
||||
setState({ ...state, generatedPassword: result });
|
||||
}
|
||||
|
||||
const passwordInputHandler = value => {
|
||||
setState({ ...state, generatedPassword: value });
|
||||
onChange(value);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="form-group">
|
||||
<label htmlFor="password">
|
||||
{title ? title : i18n.Password}
|
||||
{
|
||||
showGenerationButton && (
|
||||
<> / <button type="button" className="generate-password" onClick={() => generatePassword()}>
|
||||
{i18n.Generate}
|
||||
</button></>
|
||||
)
|
||||
}
|
||||
</label>
|
||||
<div className="password-wrapper">
|
||||
<input
|
||||
type={state.hidePassword ? 'password' : 'text'}
|
||||
className="form-control"
|
||||
id={`password_${id}`}
|
||||
name={name}
|
||||
value={state.generatedPassword}
|
||||
onChange={event => passwordInputHandler(event.target.value)}
|
||||
{...props} />
|
||||
<button type="button" onClick={() => hidePasswordHandler()}>
|
||||
{state.hidePassword ?
|
||||
<span className="eye-slash"><FontAwesomeIcon icon="eye-slash" /></span> :
|
||||
<span className="eye"><FontAwesomeIcon icon="eye" /></span>}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Password;
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const SelectInput = ({ options = [], id, name, title, optionalTitle = '', selected = '', onChange = () => { }, disabled = false }) => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
const renderOptions = () => {
|
||||
return options.map((option, index) =>
|
||||
<option key={index} selected={selected === option} value={option === i18n['Disable and Cancel Licence'] ? 'cancel' : option}>
|
||||
{option}
|
||||
</option>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
options
|
||||
? (
|
||||
<div className="form-group select-group">
|
||||
<label className="label-wrapper" htmlFor={id}>
|
||||
{title}
|
||||
<span>{optionalTitle}</span>
|
||||
</label>
|
||||
<select className="form-control" id={id} name={name} disabled={disabled} onChange={event => onChange(event.target.value)}>
|
||||
{disabled && <input type="hidden" name={name} value={selected || options[0]} />}
|
||||
{renderOptions()}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default SelectInput;
|
|
@ -1,7 +0,0 @@
|
|||
.form-group.select-group {
|
||||
label {
|
||||
span {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
const TextArea = ({ id, name, defaultValue = '', title, optionalTitle = '', rows = '3', disabled = false }) => {
|
||||
return (
|
||||
<div className="form-group">
|
||||
<label className="label-wrapper" htmlFor={id}>
|
||||
{title}
|
||||
<span>{optionalTitle}</span>
|
||||
</label>
|
||||
<textarea
|
||||
className="form-control"
|
||||
id={id}
|
||||
rows={rows}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
defaultValue={defaultValue}>
|
||||
</textarea>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TextArea;
|
|
@ -1,36 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
const TextInput = ({ id, name, title, optionalTitle = '', type = 'text', onChange = () => { }, value = '', disabled = false }) => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (value) {
|
||||
setInputValue(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const changeCheckbox = event => {
|
||||
setInputValue(event.target.value);
|
||||
onChange(event);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="form-group">
|
||||
<label className="label-wrapper" htmlFor={id}>
|
||||
{title}
|
||||
<span>{optionalTitle}</span>
|
||||
</label>
|
||||
<input
|
||||
type={type}
|
||||
name={name}
|
||||
id={id}
|
||||
onChange={changeCheckbox}
|
||||
// disabled={disabled}
|
||||
readOnly={disabled}
|
||||
value={inputValue}
|
||||
className="form-control" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TextInput;
|
|
@ -1,44 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
const TextInputWithExtraButton = props => {
|
||||
const [state, setState] = useState({
|
||||
value: '',
|
||||
previousValue: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setState({ ...state, value: props.value });
|
||||
}, [props.value]);
|
||||
|
||||
useEffect(() => {
|
||||
setState({ ...state, value: props.value, previousValue: props.value });
|
||||
}, []);
|
||||
|
||||
const changeValue = event => {
|
||||
let inputValue = event.target.value;
|
||||
|
||||
setState({ ...state, value: inputValue, previousValue: inputValue });
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="form-group">
|
||||
<label className="label-wrapper" htmlFor={props.id}>
|
||||
{props.title}
|
||||
<span className="lowercase">{props.optionalTitle ? `(${props.optionalTitle})` : ''}</span>
|
||||
</label>
|
||||
<div className="input-wrapper">
|
||||
<input
|
||||
type="text"
|
||||
name={props.name}
|
||||
id={props.id}
|
||||
className="form-control"
|
||||
onChange={changeValue}
|
||||
value={state.value}
|
||||
readOnly={state.value === 'unlimited'} />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TextInputWithExtraButton;
|
|
@ -1,36 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import './TextInputWithTextOnTheRight.scss';
|
||||
|
||||
const TextInputWithTextOnTheRight = ({ id, title, name, defaultValue = '', optionalTitle = '', disabled = false }) => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultValue) {
|
||||
setInputValue(defaultValue);
|
||||
}
|
||||
}, [defaultValue]);
|
||||
|
||||
return (
|
||||
<div className="form-group text-on-the-right">
|
||||
<label className="label-wrapper" htmlFor={id}>
|
||||
{title}
|
||||
<span>{optionalTitle || ''}</span>
|
||||
</label>
|
||||
<div className="input-wrapper">
|
||||
<input
|
||||
defaultValue={`admin_${defaultValue}`}
|
||||
type="text"
|
||||
className="form-control"
|
||||
id={id}
|
||||
value={inputValue}
|
||||
onChange={event => setInputValue(event.target.value)}
|
||||
disabled={disabled}
|
||||
name={name} />
|
||||
<span><i>{`${inputValue}`}</i></span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TextInputWithTextOnTheRight;
|
|
@ -1,11 +0,0 @@
|
|||
.form-group.text-on-the-right {
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: 15px;
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import React from 'react';
|
||||
import './Container.scss';
|
||||
|
||||
const Container = props => {
|
||||
return(
|
||||
<div className={props.className}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Container;
|
|
@ -1,47 +0,0 @@
|
|||
.l-col {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.r-col {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.w-14 {
|
||||
width: 14.3%;
|
||||
}
|
||||
|
||||
.w-20 {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.w-25 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.w-30 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.w-35 {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.w-45 {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.w-50 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.w-60 {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.w-85 {
|
||||
width: 85%;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import './Hotkeys.scss';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const Hotkeys = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keyup", toggleShortcutsLit);
|
||||
|
||||
return () => window.removeEventListener("keyup", toggleShortcutsLit);
|
||||
}, [props.reference]);
|
||||
|
||||
const toggleShortcutsLit = event => {
|
||||
let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus');
|
||||
|
||||
if (event.keyCode === 72 && !isSearchInputFocused) {
|
||||
props.toggleHotkeys();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="hotkeys-list hide" ref={props.reference}>
|
||||
<div className="head">
|
||||
<div className="name">{i18n.Shortcuts}</div>
|
||||
<div className="close" onClick={() => props.toggleHotkeys()}><FontAwesomeIcon icon="times" /></div>
|
||||
</div>
|
||||
<div className="body">
|
||||
<ul>
|
||||
<li>
|
||||
<span className="name">a</span>
|
||||
<span className="description">{i18n['Add New object']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">Ctrl + Open</span>
|
||||
<span className="description">{i18n['Save Form']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">Ctrl + Backspace</span>
|
||||
<span className="description">{i18n['Cancel saving form']}</span>
|
||||
</li>
|
||||
<li className="space-top">
|
||||
<span className="name">1</span>
|
||||
<span className="description">{i18n['Go to USER list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">2</span>
|
||||
<span className="description">{i18n['Go to WEB list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">3</span>
|
||||
<span className="description">{i18n['Go to DNS list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">4</span>
|
||||
<span className="description">{i18n['Go to MAIL list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">5</span>
|
||||
<span className="description">{i18n['Go to DB list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">6</span>
|
||||
<span className="description">{i18n['Go to CRON list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">7</span>
|
||||
<span className="description">{i18n['Go to BACKUP list']}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<span className="name">f</span>
|
||||
<span className="description">{i18n['Focus on search']}</span>
|
||||
</li>
|
||||
<li className="space-top">
|
||||
<span className="name">h</span>
|
||||
<span className="description">{i18n['Display/Close shortcuts']}</span>
|
||||
</li>
|
||||
<li className="space-top">
|
||||
<span className="name">←</span>
|
||||
<span className="description">{i18n['Move backward through top menu']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">→</span>
|
||||
<span className="description">{i18n['Move forward through top menu']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">Enter</span>
|
||||
<span className="description">{i18n['Enter focused element']}</span>
|
||||
</li>
|
||||
<li className="space-top">
|
||||
<span className="name">↑</span>
|
||||
<span className="description">{i18n['Move up through elements list']}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="name">↓</span>
|
||||
<span className="description">{i18n['Move down through elements list']}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Hotkeys;
|
|
@ -1,78 +0,0 @@
|
|||
$secondary: #fcac04;
|
||||
|
||||
.hotkeys-list {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transform: translateX(-45%);
|
||||
width: 53%;
|
||||
background: #222e44de;
|
||||
font-size: 13px;
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $secondary;
|
||||
|
||||
.name {
|
||||
text-transform: uppercase;
|
||||
padding: 5px 0 5px 10px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: $secondary;
|
||||
letter-spacing: 2px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.close {
|
||||
padding: 12px;
|
||||
opacity: 1 !important;
|
||||
|
||||
svg {
|
||||
color: $secondary;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #222e44;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
display: flex;
|
||||
|
||||
ul {
|
||||
padding: 25px 10px;
|
||||
margin: 0;
|
||||
width: 50%;
|
||||
list-style: none;
|
||||
margin-left: 3rem;
|
||||
|
||||
li {
|
||||
padding: 5px;
|
||||
|
||||
span.name {
|
||||
margin-right: 15px;
|
||||
color: $secondary;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.description {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
li.space-top {
|
||||
padding-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
import React, { Component, useEffect, useState } from 'react';
|
||||
import Container from '../Container/Container';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { useSelector } from 'react-redux';
|
||||
import './ListItem.scss';
|
||||
|
||||
const ListItem = (props) => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const [state, setState] = useState({ starred: false });
|
||||
|
||||
useEffect(() => {
|
||||
if (props.hasOwnProperty('starred')) {
|
||||
setState({ ...state, starred: Boolean(props.starred) });
|
||||
}
|
||||
}, [props.starred]);
|
||||
|
||||
const printDate = date => {
|
||||
if (date) {
|
||||
let newDate = new Date(date);
|
||||
let day = newDate.getDate();
|
||||
let month = newDate.getMonth() + 1;
|
||||
let year = newDate.getFullYear();
|
||||
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
return <div className="date">{day} {months[month - 1]} {year}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
const toggleItem = () => {
|
||||
props.checkItem();
|
||||
}
|
||||
|
||||
const starItem = () => {
|
||||
setState({ ...state, starred: !state.starred });
|
||||
props.toggleFav(!state.starred);
|
||||
}
|
||||
|
||||
const className = () => {
|
||||
const { starred } = state;
|
||||
const { checked, outdated, suspended, stopped, focused, sysInfo } = props;
|
||||
let className = 'list-item';
|
||||
|
||||
if (checked) {
|
||||
className += ' toggled';
|
||||
}
|
||||
|
||||
if (starred) {
|
||||
className += ' starred';
|
||||
}
|
||||
|
||||
if (outdated) {
|
||||
className += ' outdated';
|
||||
}
|
||||
|
||||
if (suspended) {
|
||||
className += ' suspended';
|
||||
}
|
||||
|
||||
if (stopped) {
|
||||
className += ' stopped';
|
||||
}
|
||||
|
||||
if (focused) {
|
||||
className += ' focused';
|
||||
}
|
||||
|
||||
if (sysInfo) {
|
||||
className += ' sys-info';
|
||||
}
|
||||
|
||||
return className;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={className()} id={props.id}>
|
||||
<Container className="l-col w-14">
|
||||
{printDate(props.date)}
|
||||
<div className="text-status">
|
||||
<div className="checkbox"><input type="checkbox" onChange={toggleItem} checked={props.checked} /></div>
|
||||
{props.leftNameText}
|
||||
</div>
|
||||
<div className="star">
|
||||
<div className="checkbox"><input type="checkbox" onChange={toggleItem} checked={props.checked} /></div>
|
||||
<div onClick={starItem}><FontAwesomeIcon icon="star" /></div>
|
||||
</div>
|
||||
{props.suspended && <div className='suspended'>{i18n.suspended}</div>}
|
||||
</Container>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ListItem;
|
|
@ -1,162 +0,0 @@
|
|||
$whiteBackground: #ececec;
|
||||
$primary: #2c54ac;
|
||||
$primaryLight: #2e5bb1;
|
||||
$secondary: #fcac04;
|
||||
$secondaryLight: #f8b014;
|
||||
$secondaryActive: #fdb51c;
|
||||
$textColor: #555;
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding-left: 15px;
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
padding: 25px 0;
|
||||
border-left: 2px solid white;
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: rgb(104, 104, 104);
|
||||
|
||||
&:hover .l-col div.star div svg,
|
||||
&:hover .actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.l-col {
|
||||
.suspended {
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
|
||||
.text-status {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
div.star {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
div.checkbox {
|
||||
margin: 0 25% 4px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.r-col {
|
||||
.stats {
|
||||
div > span {
|
||||
width: 50%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.c-2 div > span {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
div.bandwidth span,
|
||||
div.disk span {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 13px;
|
||||
margin: 20px 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.toggled {
|
||||
background: #feef9a;
|
||||
}
|
||||
|
||||
.list-item.starred {
|
||||
border-left: 2px solid $primary;
|
||||
|
||||
.l-col div.star {
|
||||
div > svg {
|
||||
opacity: 1;
|
||||
color: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.suspended {
|
||||
background: #eaeaea;
|
||||
color: #c0c0c0;
|
||||
|
||||
.r-col div, .r-col span {
|
||||
color: #c0c0c0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.suspended.toggled {
|
||||
background: #f2eab8;
|
||||
color: #b2ac87;
|
||||
|
||||
.l-col,
|
||||
.r-col .name,
|
||||
.r-col .stats {
|
||||
color: #b2ac87 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.outdated {
|
||||
background: #ffcaca;
|
||||
border-left: 5px solid #ff6f6f;
|
||||
}
|
||||
|
||||
.list-item.toggled.outdated {
|
||||
background: #755d5d;
|
||||
color: black;
|
||||
|
||||
.stat {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.stopped {
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
.list-item.focused {
|
||||
border-left: 2px solid $secondaryLight;
|
||||
|
||||
.l-col div.star {
|
||||
div > svg {
|
||||
color: $secondaryLight;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
opacity: 1;
|
||||
|
||||
div > a,
|
||||
div > button {
|
||||
padding-top: 6.5px;
|
||||
padding-bottom: 6.5px;
|
||||
|
||||
.shortcut-button {
|
||||
border-radius: 50%;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-left: 15px;
|
||||
background: $secondaryLight;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.shortcut-button.html-unicode {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.shortcut-button.del {
|
||||
text-transform: capitalize;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../AddItemLayout/AddItemLayout.scss';
|
||||
import './LoginLayout.scss';
|
||||
|
||||
const LoginLayout = ({ children }) => {
|
||||
return (
|
||||
<div className="login-layout">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoginLayout;
|
|
@ -1,4 +0,0 @@
|
|||
.login-layout {
|
||||
margin-top: 1rem;
|
||||
padding: 2rem 3rem;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import './Modal.scss';
|
||||
|
||||
const Modal = ({ show, text, onSave, onCancel, showSaveButton = true, showCancelButton = true }) => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={`modal fade ${show ? 'show' : ''}`} id="c-panel-modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" style={{ display: show ? 'block' : 'none' }}>
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title" id="exampleModalLabel">{i18n.Confirmation}</h5>
|
||||
<button type="button" onClick={() => onCancel()} className="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
{text}
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
{showCancelButton ? <button onClick={() => onCancel()} type="button" className="btn btn-secondary" data-dismiss="modal">{i18n.Cancel}</button> : ''}
|
||||
{showSaveButton ? <button onClick={() => onSave()} type="button" className="btn btn-primary">{i18n.OK}</button> : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export default Modal;
|
|
@ -1,20 +0,0 @@
|
|||
$primary: #2c54ac;
|
||||
|
||||
div.modal {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
div.content .modal .modal-content {
|
||||
width: 75%;
|
||||
|
||||
.modal-header button.close {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
.btn-primary {
|
||||
background: $primary;
|
||||
border: 1px solid $primary;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { addActiveElement, removeFocusedElement } from "../../../actions/MainNavigation/mainNavigationActions";
|
||||
import AddItemLayout from '../../ControlPanel/AddItemLayout/AddItemLayout';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { addCronJob } from '../../../ControlPanelService/Cron';
|
||||
import Toolbar from '../../MainNav/Toolbar/Toolbar';
|
||||
import Generator from '../Generator/Generator';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import Spinner from '../../Spinner/Spinner';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import './AddCronJob.scss';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
const AddCronJob = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const token = localStorage.getItem("token");
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const [state, setState] = useState({
|
||||
loading: false,
|
||||
okMessage: '',
|
||||
errorMessage: '',
|
||||
generatedCronJob: {
|
||||
h_min: '*',
|
||||
h_hour: '*',
|
||||
h_day: '*',
|
||||
h_wday: '*',
|
||||
h_month: '*'
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(addActiveElement('/list/cron/'));
|
||||
dispatch(removeFocusedElement());
|
||||
}, []);
|
||||
|
||||
const submitFormHandler = event => {
|
||||
event.preventDefault();
|
||||
let newCronJob = {};
|
||||
|
||||
for (var [name, value] of (new FormData(event.target)).entries()) {
|
||||
newCronJob[name] = value;
|
||||
}
|
||||
|
||||
if (Object.keys(newCronJob).length !== 0 && newCronJob.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
addCronJob(newCronJob)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
|
||||
|
||||
if (errorMessage) {
|
||||
setState({ ...state, errorMessage, okMessage, loading: false });
|
||||
} else {
|
||||
dispatch(refreshCounters()).then(() => {
|
||||
setState({ ...state, okMessage, errorMessage: '', loading: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
const saveGeneratedCronJob = generatedCronJob => {
|
||||
setState({
|
||||
...state,
|
||||
generatedCronJob
|
||||
});
|
||||
}
|
||||
|
||||
const changeInput = input => {
|
||||
let updatedGeneratedCronJob = {
|
||||
...state.generatedCronJob,
|
||||
[input.id]: input.value
|
||||
};
|
||||
|
||||
setState({
|
||||
...state,
|
||||
generatedCronJob: updatedGeneratedCronJob
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-template add-cron">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.CRON}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false}>
|
||||
<div></div>
|
||||
<div className="search-toolbar-name">{i18n['Adding Cron Job']}</div>
|
||||
<div className="error">
|
||||
<span className="error-message">
|
||||
{state.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
|
||||
{state.errorMessage}</span>
|
||||
</div>
|
||||
<div className="success">
|
||||
<span className="ok-message">
|
||||
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
|
||||
<span>{HtmlParser(state.okMessage)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<AddItemLayout>
|
||||
{state.loading ? <Spinner /> : (
|
||||
<form onSubmit={event => submitFormHandler(event)}>
|
||||
<input type="hidden" name="ok" value="add" />
|
||||
<input type="hidden" name="token" value={token} />
|
||||
|
||||
<div className="form-group command">
|
||||
<label htmlFor="command">{i18n.Command ?? 'Command'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="command"
|
||||
name="v_cmd" />
|
||||
</div>
|
||||
|
||||
<div className="cron-form-body">
|
||||
|
||||
<div className="body-col-1">
|
||||
<div className="form-group">
|
||||
<label htmlFor="h_min">{i18n.Minute ?? 'Minute'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="h_min"
|
||||
onChange={event => changeInput(event.target)}
|
||||
value={state.generatedCronJob.h_min}
|
||||
name="v_min" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="h_hour">{i18n.Hour ?? 'Hour'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="h_hour"
|
||||
onChange={event => changeInput(event.target)}
|
||||
value={state.generatedCronJob.h_hour}
|
||||
name="v_hour" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="h_day">{i18n.Day ?? 'Day'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="h_day"
|
||||
onChange={event => changeInput(event.target)}
|
||||
value={state.generatedCronJob.h_day}
|
||||
name="v_day" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="h_month">{i18n.Month ?? 'Month'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="h_month"
|
||||
onChange={event => changeInput(event.target)}
|
||||
value={state.generatedCronJob.h_month}
|
||||
name="v_month" />
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="h_wday">{i18n['Day of week'] ?? 'Days of week'}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="h_wday"
|
||||
onChange={event => changeInput(event.target)}
|
||||
value={state.generatedCronJob.h_wday}
|
||||
name="v_wday" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="body-col-2">
|
||||
<Generator mode="add" generatedCronJob={saveGeneratedCronJob} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Add ?? 'Add'}</button>
|
||||
<button type="button" className="back" onClick={() => history.push('/list/cron/')}>{i18n.Back ?? 'Back'}</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</AddItemLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddCronJob;
|
|
@ -1,31 +0,0 @@
|
|||
.edit-template.add-cron {
|
||||
form {
|
||||
.form-group {
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
width: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group.command {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cron-form-body {
|
||||
display: flex;
|
||||
|
||||
.body-col-1 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.body-col-2 {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 1.7rem 1rem;
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import ListItem from '../ControlPanel/ListItem/ListItem';
|
||||
import Container from '../ControlPanel/Container/Container';
|
||||
import './CronJob.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const CronJob = props => {
|
||||
const { data } = props;
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const token = localStorage.getItem("token");
|
||||
|
||||
const toggleFav = (starred) => {
|
||||
if (starred) {
|
||||
props.toggleFav(props.data.NAME, 'add');
|
||||
} else {
|
||||
props.toggleFav(props.data.NAME, 'delete');
|
||||
}
|
||||
}
|
||||
|
||||
const checkItem = () => {
|
||||
props.checkItem(props.data.NAME);
|
||||
}
|
||||
|
||||
const handleSuspend = () => {
|
||||
let suspendedStatus = data.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend' === 'yes' ? 'unsuspend' : 'suspend';
|
||||
props.handleModal(data.suspend_conf, `/api/v1/${suspendedStatus}/cron/index.php?job=${data.NAME}`);
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
props.handleModal(data.delete_conf, `/api/v1/delete/cron/index.php?job=${data.NAME}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
id={data.NAME}
|
||||
date={data.DATE}
|
||||
checkItem={checkItem}
|
||||
toggleFav={toggleFav}
|
||||
focused={data.FOCUSED}
|
||||
starred={data.STARRED}
|
||||
checked={data.isChecked}
|
||||
suspended={data.SUSPENDED === 'yes'}>
|
||||
|
||||
<Container className="cron-jobs-list r-col w-85">
|
||||
<div className="name">{data.CMD}</div>
|
||||
<div className="stats">
|
||||
<Container className="cron-col">
|
||||
<div>{i18n.Min} <span>{data.MIN}</span></div>
|
||||
</Container>
|
||||
<Container className="cron-col">
|
||||
<div>{i18n.Hour} <span>{data.HOUR}</span></div>
|
||||
</Container>
|
||||
<Container className="cron-col">
|
||||
<div>{i18n.Day} <span>{data.DAY}</span></div>
|
||||
</Container>
|
||||
<Container className="cron-col">
|
||||
<div>{i18n.Month} <span>{data.MONTH}</span></div>
|
||||
</Container>
|
||||
<Container className="cron-col">
|
||||
<div>{i18n['Day of week']} <span>{data.WDAY}</span></div>
|
||||
</Container>
|
||||
</div>
|
||||
</Container>
|
||||
<div className="actions">
|
||||
|
||||
<div>
|
||||
<Link className="link-edit" to={`/edit/cron/?job=${data.NAME}`}>
|
||||
{i18n.edit}
|
||||
{data.FOCUSED ? <span className="shortcut-button html-unicode">↩</span> : <FontAwesomeIcon icon="pen" />}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
className="link-gray"
|
||||
onClick={() => handleSuspend()}>
|
||||
{i18n[data.suspend_action]}
|
||||
{data.FOCUSED ? <span className="shortcut-button">S</span> : <FontAwesomeIcon icon={data.SUSPENDED === 'yes' ? 'unlock' : 'lock'} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="link-delete" onClick={() => handleDelete()}>
|
||||
{i18n.Delete}
|
||||
{data.FOCUSED ? <span className="shortcut-button del">Del</span> : <FontAwesomeIcon icon="times" />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default CronJob;
|
|
@ -1,13 +0,0 @@
|
|||
.cron-jobs-list.r-col .name {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.cron-col > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
span {
|
||||
font-size: 18px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { addActiveElement, removeFocusedElement } from "../../../actions/MainNavigation/mainNavigationActions";
|
||||
import TextInput from '../../ControlPanel/AddItemLayout/Form/TextInput/TextInput';
|
||||
import { getCronJobInfo, updateCronJob } from '../../../ControlPanelService/Cron';
|
||||
import AddItemLayout from '../../ControlPanel/AddItemLayout/AddItemLayout';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Spinner from '../../../components/Spinner/Spinner';
|
||||
import Toolbar from '../../MainNav/Toolbar/Toolbar';
|
||||
import Generator from '../Generator/Generator';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import QS from 'qs';
|
||||
|
||||
import './EditCronJob.scss';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
const EditMail = props => {
|
||||
const token = localStorage.getItem("token");
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const [state, setState] = useState({
|
||||
data: {},
|
||||
errorMessage: '',
|
||||
okMessage: '',
|
||||
loading: false,
|
||||
generatedCronJob: {
|
||||
h_min: '*',
|
||||
h_hour: '*',
|
||||
h_day: '*',
|
||||
h_wday: '*',
|
||||
h_month: '*'
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
let queryParams = QS.parse(history.location.search, { ignoreQueryPrefix: true });
|
||||
const { job } = queryParams;
|
||||
|
||||
dispatch(addActiveElement('/list/cron/'));
|
||||
dispatch(removeFocusedElement());
|
||||
|
||||
if (job) {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
getCronJobInfo(job)
|
||||
.then(response => {
|
||||
setState({
|
||||
...state,
|
||||
generatedCronJob: {
|
||||
...state.generatedCronJob,
|
||||
h_min: response.data.min,
|
||||
h_hour: response.data.hour,
|
||||
h_day: response.data.day,
|
||||
h_wday: response.data.wday,
|
||||
h_month: response.data.month
|
||||
},
|
||||
data: response.data,
|
||||
errorMessage: response.data['error_msg'],
|
||||
okMessage: response.data['ok_msg'],
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const submitFormHandler = event => {
|
||||
event.preventDefault();
|
||||
let updatedJob = {};
|
||||
|
||||
for (var [name, value] of (new FormData(event.target)).entries()) {
|
||||
updatedJob[name] = value;
|
||||
}
|
||||
|
||||
if (Object.keys(updatedJob).length !== 0 && updatedJob.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
updateCronJob(updatedJob, state.data.job)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
|
||||
|
||||
if (errorMessage) {
|
||||
setState({ ...state, errorMessage, okMessage, loading: false });
|
||||
} else {
|
||||
dispatch(refreshCounters()).then(() => {
|
||||
setState({ ...state, okMessage, errorMessage: '', loading: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
const saveGeneratedCronJob = generatedCronJob => {
|
||||
setState({
|
||||
...state,
|
||||
generatedCronJob
|
||||
});
|
||||
}
|
||||
|
||||
const changeInput = input => {
|
||||
let updatedGeneratedCronJob = {
|
||||
...state.generatedCronJob,
|
||||
[input.id]: input.value
|
||||
};
|
||||
|
||||
setState({
|
||||
...state,
|
||||
generatedCronJob: updatedGeneratedCronJob
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-template edit-cron">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.CRON}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false}>
|
||||
<div></div>
|
||||
<div className="search-toolbar-name">{i18n['Editing Cron Job']}</div>
|
||||
<div className="error">
|
||||
<span className="error-message">
|
||||
{state.data.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}
|
||||
</span>
|
||||
</div>
|
||||
<div className="success">
|
||||
<span className="ok-message">
|
||||
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<AddItemLayout date={state.data.date} time={state.data.time} status={state.data.status}>
|
||||
{state.loading ? <Spinner /> :
|
||||
<form onSubmit={event => submitFormHandler(event)} id="edit-cron">
|
||||
<input type="hidden" name="save" value="save" />
|
||||
<input type="hidden" name="token" value={token} />
|
||||
|
||||
<TextInput id="command" name="v_cmd" title={i18n['Command']} value={state.data.cmd} />
|
||||
|
||||
<div className="cron-form-body">
|
||||
|
||||
<div className="body-col-1">
|
||||
<TextInput
|
||||
value={state.generatedCronJob.h_min}
|
||||
onChange={changeInput}
|
||||
title={i18n['Minute']}
|
||||
name="v_min"
|
||||
id="h_min" />
|
||||
|
||||
<TextInput
|
||||
value={state.generatedCronJob.h_hour}
|
||||
onChange={changeInput}
|
||||
title={i18n['Hour']}
|
||||
name="v_hour"
|
||||
id="h_hour" />
|
||||
|
||||
<TextInput
|
||||
value={state.generatedCronJob.h_day}
|
||||
onChange={changeInput}
|
||||
title={i18n['Day']}
|
||||
name="v_day"
|
||||
id="h_day" />
|
||||
|
||||
<TextInput
|
||||
value={state.generatedCronJob.h_month}
|
||||
onChange={changeInput}
|
||||
title={i18n['Month']}
|
||||
name="v_month"
|
||||
id="h_month" />
|
||||
|
||||
<TextInput
|
||||
value={state.generatedCronJob.h_wday}
|
||||
title={i18n['Day of week']}
|
||||
onChange={changeInput}
|
||||
name="v_wday"
|
||||
id="h_wday" />
|
||||
</div>
|
||||
|
||||
<div className="body-col-2">
|
||||
<Generator mode="edit" job={state.data.job} generatedCronJob={saveGeneratedCronJob} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Save}</button>
|
||||
<button type="button" className="back" onClick={() => history.push('/list/cron/')}>{i18n.Back}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
}
|
||||
</AddItemLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditMail;
|
|
@ -1,39 +0,0 @@
|
|||
.edit-cron {
|
||||
form {
|
||||
.form-group {
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
width: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group.command {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cron-form-body {
|
||||
display: flex;
|
||||
|
||||
.body-col-1 {
|
||||
width: 30%;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.body-col-2 {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 1.7rem 1rem;
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#edit-cron > .form-group input {
|
||||
width: 95% !important;
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import RunCommandSelect from './RunCommandSelect/RunCommandSelect';
|
||||
import SelectsWrapper from './OtherSelects/SelectsWrapper';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import QS from 'qs';
|
||||
|
||||
import './Generator.scss';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const Generator = props => {
|
||||
const formElement = useRef(null);
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const history = useHistory();
|
||||
const [state, setState] = useState({
|
||||
activeTab: '1'
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
let parsedQuery = QS.parse(history.location.search, { ignoreQueryPrefix: true });
|
||||
let activeTab = parsedQuery.activeTab || '1';
|
||||
|
||||
setState({ ...state, activeTab });
|
||||
}, [history.location.search]);
|
||||
|
||||
const activeClassName = tab => {
|
||||
return state.activeTab === tab ? 'active' : '';
|
||||
}
|
||||
|
||||
const emulateFormSubmit = () => {
|
||||
let generatedCronJob = {};
|
||||
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
let iterableFormElement = formElement.current[i];
|
||||
|
||||
generatedCronJob[iterableFormElement.name] = iterableFormElement.value;
|
||||
}
|
||||
|
||||
props.generatedCronJob(generatedCronJob);
|
||||
}
|
||||
|
||||
const formatLink = tab => {
|
||||
const { job, mode } = props;
|
||||
|
||||
return `/${mode}/cron/?${!!job ? `job=${job}&` : ''}activeTab=${tab}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="cron-job-generator">
|
||||
<div className="header">
|
||||
<Link to={formatLink('1')} className={activeClassName('1')}>{i18n.Minutes}</Link>
|
||||
<Link to={formatLink('2')} className={activeClassName('2')}>{i18n.Hourly}</Link>
|
||||
<Link to={formatLink('3')} className={activeClassName('3')}>{i18n.Daily}</Link>
|
||||
<Link to={formatLink('4')} className={activeClassName('4')}>{i18n.Weekly}</Link>
|
||||
<Link to={formatLink('5')} className={activeClassName('5')}>{i18n.Monthly}</Link>
|
||||
</div>
|
||||
|
||||
<div className="body">
|
||||
|
||||
<form ref={formElement}>
|
||||
<RunCommandSelect activeTab={state.activeTab} />
|
||||
|
||||
<SelectsWrapper activeTab={state.activeTab} />
|
||||
|
||||
<div className="form-actions">
|
||||
<button type="button" onClick={emulateFormSubmit}>{i18n.Generate}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Generator;
|
|
@ -1,119 +0,0 @@
|
|||
$whiteBackground: #ececec;
|
||||
$primary: #2c54ac;
|
||||
$primaryLight: #d7dcef;
|
||||
$primaryActive: #1e5cb2;
|
||||
$secondary: #fcac04;
|
||||
$secondaryLight: #f8b014;
|
||||
$secondaryActive: #fdb51c;
|
||||
$hoverButtonText: #2c54ac;
|
||||
$activeButtonText: #fff;
|
||||
$textColor: #555;
|
||||
|
||||
.cron-job-generator {
|
||||
border: 1px solid #d9d9d9;
|
||||
padding: 1rem 1.5rem;
|
||||
margin-left: 2rem;
|
||||
width: 90%;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
padding: .4rem 0;
|
||||
|
||||
a {
|
||||
color: #222222;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
font-weight: bolder;
|
||||
margin-right: 2.3rem;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: $secondaryLight;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $primaryActive;
|
||||
}
|
||||
}
|
||||
|
||||
a.active {
|
||||
color: $secondaryActive;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 2rem 0 .4rem;
|
||||
|
||||
form {
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
width: 26%;
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group.minute select {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
border-radius: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #909090;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
outline: none;
|
||||
border-color: $primaryActive;
|
||||
box-shadow: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group select {
|
||||
padding: .4rem .25rem;
|
||||
border-color: #d9d9d9;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
button {
|
||||
background: $primary;
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
padding: .35rem 1.1rem;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
color: $hoverButtonText;
|
||||
background: $primaryLight;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $activeButtonText;
|
||||
background: $primaryActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-group.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.form-group.hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { generatorOptions } from '../../../../ControlPanelService/GeneratorOptions';
|
||||
|
||||
export default function FifthTabSelects() {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const { dailyMinutesOptions, hoursOptions, dateOptions } = generatorOptions(i18n);
|
||||
|
||||
const renderDate = () => {
|
||||
return dateOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
const renderHours = () => {
|
||||
return hoursOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
const renderMinutes = () => {
|
||||
return dailyMinutesOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='fifth-tab-selects'>
|
||||
<input type="hidden" name="h_wday" value="*" />
|
||||
|
||||
<div className="form-group date">
|
||||
<label htmlFor="run-command">{i18n.Date ?? 'Date'}:</label>
|
||||
<select className="form-control" name="h_day">
|
||||
{renderDate()}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group hour">
|
||||
<label htmlFor="run-command">{i18n.Hour ?? 'Hour'}:</label>
|
||||
<select className="form-control" name="h_hour">
|
||||
{renderHours()}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group minute">
|
||||
<label htmlFor="run-command">{i18n.Minute ?? 'Minute'}:</label>
|
||||
<select className="form-control" name="h_min">
|
||||
{renderMinutes()}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { generatorOptions } from '../../../../ControlPanelService/GeneratorOptions';
|
||||
|
||||
export default function FourthTabSelects() {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const { dailyMinutesOptions, hoursOptions } = generatorOptions(i18n);
|
||||
|
||||
const renderHours = () => {
|
||||
return hoursOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
const renderMinutes = () => {
|
||||
return dailyMinutesOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='fourth-tab-selects'>
|
||||
<input type="hidden" name="h_month" value="*" />
|
||||
<input type="hidden" name="h_day" value="*" />
|
||||
|
||||
<div className="form-group hour">
|
||||
<label htmlFor="run-command">{i18n.Hour ?? 'Hour'}:</label>
|
||||
<select className="form-control" name="h_hour">
|
||||
{renderHours()}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group minute">
|
||||
<label htmlFor="run-command">{i18n.Minute ?? 'Minute'}:</label>
|
||||
<select className="form-control" name="h_min">
|
||||
{renderMinutes()}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { generatorOptions } from '../../../../ControlPanelService/GeneratorOptions';
|
||||
|
||||
export default function SecondTabSelects() {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const { hourlyMinutesOptions } = generatorOptions(i18n);
|
||||
|
||||
const renderOptions = () => {
|
||||
return hourlyMinutesOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='second-tab-selects'>
|
||||
<input type="hidden" name="h_day" value="*" />
|
||||
<input type="hidden" name="h_month" value="*" />
|
||||
<input type="hidden" name="h_wday" value="*" />
|
||||
|
||||
<div className="form-group minute">
|
||||
<label htmlFor="run-command">{i18n.Minute ?? 'Minute'}:</label>
|
||||
<select className="form-control" name="h_min">
|
||||
{renderOptions()}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import SecondTabSelects from './SecondTabSelects';
|
||||
import ThirdTabSelects from './ThirdTabSelects';
|
||||
import FourthTabSelects from './FourthTabSelects';
|
||||
import FifthTabSelects from './FifthTabSelects';
|
||||
|
||||
import './SelectsWrapper.scss';
|
||||
|
||||
const OtherSelects = props => {
|
||||
const [state, setState] = useState({
|
||||
activeTab: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setState({ ...state, activeTab: props.activeTab });
|
||||
}, [props.activeTab]);
|
||||
|
||||
const renderSelects = () => {
|
||||
switch (state.activeTab) {
|
||||
case '1': return (
|
||||
<div>
|
||||
<input type="hidden" name="h_hour" value="*" />
|
||||
<input type="hidden" name="h_day" value="*" />
|
||||
<input type="hidden" name="h_month" value="*" />
|
||||
<input type="hidden" name="h_wday" value="*" />
|
||||
</div>
|
||||
)
|
||||
case '2': return <SecondTabSelects />;
|
||||
case '3': return <ThirdTabSelects />;
|
||||
case '4': return <FourthTabSelects />;
|
||||
case '5': return <FifthTabSelects />;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`tab-${state.activeTab}`}>
|
||||
{renderSelects()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default OtherSelects;
|
|
@ -1,60 +0,0 @@
|
|||
.cron-form-body {
|
||||
.third-tab-selects,
|
||||
.fourth-tab-selects {
|
||||
display: flex;
|
||||
|
||||
div.hour {
|
||||
select {
|
||||
width: 70px;
|
||||
margin-left: 4.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
div.minute {
|
||||
label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
select {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fifth-tab-selects {
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
width: 10%;
|
||||
|
||||
select {
|
||||
width: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
> div.date {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
> div.minute {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
> div.hour {
|
||||
width: 155px;
|
||||
margin-left: 1rem;
|
||||
|
||||
select {
|
||||
margin-left: .75rem;
|
||||
}
|
||||
}
|
||||
|
||||
> div.date {
|
||||
width: 240px;
|
||||
|
||||
select {
|
||||
margin-left: 5.85rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { generatorOptions } from '../../../../ControlPanelService/GeneratorOptions';
|
||||
|
||||
export default function ThirdTabSelects() {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const { dailyMinutesOptions, hoursOptions } = generatorOptions(i18n);
|
||||
|
||||
const renderHours = () => {
|
||||
return hoursOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
const renderOptions = () => {
|
||||
return dailyMinutesOptions.map((option, index) => <option key={index} value={option.value}>{option.name}</option>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='third-tab-selects'>
|
||||
<input type="hidden" name="h_month" value="*" />
|
||||
<input type="hidden" name="h_wday" value="*" />
|
||||
|
||||
<div className="form-group hour">
|
||||
<label htmlFor="run-command">{i18n.Hour ?? 'Hour'}:</label>
|
||||
<select className="form-control" name="h_hour">
|
||||
{renderHours()}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group minute">
|
||||
<label htmlFor="run-command">{i18n.Minute ?? 'Minute'}:</label>
|
||||
<select className="form-control" name="h_min">
|
||||
{renderOptions()}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { generatorOptions } from '../../../../ControlPanelService/GeneratorOptions';
|
||||
|
||||
const RunCommandSelect = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
const [state, setState] = useState({
|
||||
activeTab: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setState({ ...state, activeTab: props.activeTab });
|
||||
}, [props]);
|
||||
|
||||
const renderOptions = () => {
|
||||
const { daysRunCommandsOptions, hoursRunCommandsOptions, minutesRunCommandsOptions, monthlyRunCommandOptions, weeklyRunCommandOptions } = generatorOptions(i18n);
|
||||
|
||||
switch (state.activeTab) {
|
||||
case '1': return minutesRunCommandsOptions.map(option => <option value={option.value}>{option.name}</option>);
|
||||
case '2': return hoursRunCommandsOptions.map(option => <option value={option.value}>{option.name}</option>);
|
||||
case '3': return daysRunCommandsOptions.map(option => <option value={option.value}>{option.name}</option>);
|
||||
case '4': return weeklyRunCommandOptions.map(option => <option value={option.value}>{option.name}</option>);
|
||||
case '5': return monthlyRunCommandOptions.map(option => <option value={option.value}>{option.name}</option>);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
const selectName = () => {
|
||||
switch (state.activeTab) {
|
||||
case '1': return 'h_min';
|
||||
case '2': return 'h_hour';
|
||||
case '3': return 'h_day';
|
||||
case '4': return 'h_wday';
|
||||
case '5': return 'h_month';
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="form-group run-command">
|
||||
<label htmlFor="run-command">{i18n['Run Command']}:</label>
|
||||
<select className="form-control" name={selectName()}>
|
||||
{renderOptions()}
|
||||
</select>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
export default RunCommandSelect;
|
|
@ -1,145 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { addActiveElement, removeFocusedElement } from "../../../actions/MainNavigation/mainNavigationActions";
|
||||
import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
|
||||
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
|
||||
import AddItemLayout from '../../ControlPanel/AddItemLayout/AddItemLayout';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { addDomainNameSystemRecord } from '../../../ControlPanelService/Dns';
|
||||
import Toolbar from '../../MainNav/Toolbar/Toolbar';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import Spinner from '../../Spinner/Spinner';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import './AddDNSRecord.scss'
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
export default function AddDNSRecord(props) {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const dispatch = useDispatch();
|
||||
const token = localStorage.getItem("token");
|
||||
const history = useHistory();
|
||||
const [state, setState] = useState({
|
||||
data: {},
|
||||
selectOptions: [
|
||||
'A',
|
||||
'AAAA',
|
||||
'NS',
|
||||
'CNAME',
|
||||
'MX',
|
||||
'TXT',
|
||||
'SRV',
|
||||
'DNSKEY',
|
||||
'KEY',
|
||||
'IPSECKEY',
|
||||
'PTR',
|
||||
'SPF',
|
||||
'TLSA',
|
||||
'CAA'
|
||||
],
|
||||
loading: false,
|
||||
okMessage: '',
|
||||
errorMessage: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(addActiveElement(`/list/dns/`));
|
||||
dispatch(removeFocusedElement());
|
||||
}, []);
|
||||
|
||||
const submitFormHandler = event => {
|
||||
event.preventDefault();
|
||||
let newDnsRecord = {};
|
||||
|
||||
for (var [name, value] of (new FormData(event.target)).entries()) {
|
||||
newDnsRecord[name] = value;
|
||||
}
|
||||
|
||||
newDnsRecord['ok_rec'] = 'add';
|
||||
newDnsRecord['token'] = token;
|
||||
newDnsRecord['v_domain'] = props.domain;
|
||||
|
||||
if (Object.keys(newDnsRecord).length !== 0 && newDnsRecord.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
addDomainNameSystemRecord(newDnsRecord)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
|
||||
|
||||
if (errorMessage) {
|
||||
setState({ ...state, errorMessage, okMessage, loading: false });
|
||||
} else {
|
||||
dispatch(refreshCounters()).then(() => {
|
||||
setState({ ...state, okMessage, errorMessage: '', loading: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-template add-dns-record">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.DNS}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false}>
|
||||
<div></div>
|
||||
<div className="search-toolbar-name">{i18n['Adding DNS Record']}</div>
|
||||
<div className="error">
|
||||
<span className="error-message">
|
||||
{state.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
|
||||
{state.errorMessage}</span>
|
||||
</div>
|
||||
<div className="success">
|
||||
<span className="ok-message">
|
||||
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
|
||||
<span>{HtmlParser(state.okMessage)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<AddItemLayout>
|
||||
{state.loading ? <Spinner /> : (
|
||||
<form onSubmit={event => submitFormHandler(event)}>
|
||||
<TextInput
|
||||
title={i18n['Domain']}
|
||||
value={props.domain}
|
||||
name="v_domain"
|
||||
id="domain"
|
||||
disabled />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Record']}
|
||||
name="v_rec"
|
||||
id="domain" />
|
||||
|
||||
<SelectInput
|
||||
options={state.selectOptions}
|
||||
title={i18n['Type']}
|
||||
name="v_type"
|
||||
id="type" />
|
||||
|
||||
<TextInput
|
||||
title={i18n['IP or Value']}
|
||||
name="v_val"
|
||||
id="val" />
|
||||
|
||||
<TextInput
|
||||
optionalTitle={`(${i18n['optional']})`}
|
||||
title={i18n['Priority']}
|
||||
name="v_priority"
|
||||
id="priority" />
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Add}</button>
|
||||
<button type="button" className="back" onClick={() => history.push(`/list/dns/?domain=${props.domain}`)}>{i18n.Back}</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</AddItemLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Container from '../ControlPanel/Container/Container';
|
||||
import ListItem from '../ControlPanel/ListItem/ListItem';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
export default function DnsRecord({ data, domain, handleModal, ...props }) {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
||||
const toggleFav = (starred) => {
|
||||
if (starred) {
|
||||
props.toggleFav(data.NAME, 'add');
|
||||
} else {
|
||||
props.toggleFav(data.NAME, 'delete');
|
||||
}
|
||||
}
|
||||
|
||||
const checkItem = () => {
|
||||
props.checkItem(data.NAME);
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
handleModal(data.delete_conf, `/api/v1/delete/dns/?domain=${domain}&record_id=${data.ID}`);
|
||||
}
|
||||
|
||||
const handleSuspend = () => {
|
||||
handleModal(data.suspend_conf, `/api/v1/${data.suspend_action}/dns/?domain=${domain}&record_id=${data.ID}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
id={data.NAME}
|
||||
date={data.DATE}
|
||||
toggleFav={toggleFav}
|
||||
checkItem={checkItem}
|
||||
starred={data.STARRED}
|
||||
focused={data.FOCUSED}
|
||||
checked={data.isChecked}
|
||||
suspended={data.SUSPENDED === 'yes'}>
|
||||
|
||||
<Container className="r-col w-85">
|
||||
<div className="name">{data.dnsRecord}</div>
|
||||
<br />
|
||||
<div className="stats">
|
||||
<Container className="c-1">
|
||||
<span className="stat">{`${data.RECORD.substring(0, 12)}${data.RECORD.length > 12 ? '...' : ''}`}</span>
|
||||
</Container>
|
||||
<Container className="c-2">
|
||||
<span className="stat">{data.TYPE}</span>
|
||||
</Container>
|
||||
<Container className="c-3">
|
||||
<span className="stat">{data.PRIORITY}</span>
|
||||
</Container>
|
||||
<Container className="c-4 long-value">
|
||||
<span className="stat">{data.VALUE}</span>
|
||||
</Container>
|
||||
</div>
|
||||
</Container>
|
||||
<div className="actions">
|
||||
<div>
|
||||
<Link className="link-edit" to={`/edit/dns/?domain=${domain}&record_id=${data.ID}`}>
|
||||
{i18n.edit}
|
||||
{data.FOCUSED ? <span className="shortcut-button html-unicode">↩</span> : <FontAwesomeIcon icon="pen" />}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
className="link-gray"
|
||||
onClick={handleSuspend}>
|
||||
{data.suspend_action}
|
||||
{data.FOCUSED ? <span className="shortcut-button">S</span> : <FontAwesomeIcon icon={data.SUSPENDED === 'yes' ? 'unlock' : 'lock'} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="link-delete" onClick={() => handleDelete()}>
|
||||
{i18n.Delete}
|
||||
{data.FOCUSED ? <span className="shortcut-button del">Del</span> : <FontAwesomeIcon icon="times" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { addActiveElement, removeFocusedElement } from "../../../actions/MainNavigation/mainNavigationActions";
|
||||
import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
|
||||
import TextInput from '../../ControlPanel/AddItemLayout/Form/TextInput/TextInput';
|
||||
import AddItemLayout from '../../ControlPanel/AddItemLayout/AddItemLayout';
|
||||
import { updateDNS, getDNSRecordInfo } from 'src/ControlPanelService/Dns';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Spinner from '../../../components/Spinner/Spinner';
|
||||
import Toolbar from '../../MainNav/Toolbar/Toolbar';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import QS from 'qs';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
export default function EditDNSRecord(props) {
|
||||
const token = localStorage.getItem("token");
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const [state, setState] = useState({
|
||||
data: {},
|
||||
selectOptions: [
|
||||
'A',
|
||||
'AAAA',
|
||||
'NS',
|
||||
'CNAME',
|
||||
'MX',
|
||||
'TXT',
|
||||
'SRV',
|
||||
'DNSKEY',
|
||||
'KEY',
|
||||
'IPSECKEY',
|
||||
'PTR',
|
||||
'SPF',
|
||||
'TLSA',
|
||||
'CAA'
|
||||
],
|
||||
loading: false,
|
||||
errorMessage: '',
|
||||
okMessage: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const { domain, record_id } = props;
|
||||
|
||||
dispatch(addActiveElement('/list/dns/'));
|
||||
dispatch(removeFocusedElement());
|
||||
|
||||
if (domain) {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
getDNSRecordInfo(domain, record_id)
|
||||
.then(response => {
|
||||
setState({
|
||||
...state,
|
||||
data: response.data,
|
||||
errorMessage: response.data['error_msg'],
|
||||
okMessage: response.data['ok_msg'],
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const submitFormHandler = event => {
|
||||
event.preventDefault();
|
||||
let updatedRecord = {};
|
||||
|
||||
for (var [name, value] of (new FormData(event.target)).entries()) {
|
||||
updatedRecord[name] = value;
|
||||
}
|
||||
|
||||
updatedRecord['v_domain'] = state.data.domain;
|
||||
updatedRecord['v_record_id'] = props.record_id;
|
||||
updatedRecord['v_type'] = state.data.type;
|
||||
|
||||
if (Object.keys(updatedRecord).length !== 0 && updatedRecord.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
updateDNS(updatedRecord, props.domain, props.record_id)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
|
||||
|
||||
if (errorMessage) {
|
||||
setState({ ...state, errorMessage, okMessage, loading: false });
|
||||
} else {
|
||||
dispatch(refreshCounters()).then(() => {
|
||||
setState({ ...state, okMessage, errorMessage: '', loading: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="edit-template edit-dns-rec">
|
||||
<Helmet>
|
||||
<title>{`Vesta - ${i18n.DNS}`}</title>
|
||||
</Helmet>
|
||||
<Toolbar mobile={false}>
|
||||
<div></div>
|
||||
<div className="search-toolbar-name">{i18n['Editing DNS Record']}</div>
|
||||
<div className="error">
|
||||
<span className="error-message">
|
||||
{state.data.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}
|
||||
</span>
|
||||
</div>
|
||||
<div className="success">
|
||||
<span className="ok-message">
|
||||
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<AddItemLayout date={state.data.date} time={state.data.time} status={state.data.status}>
|
||||
{state.loading ? <Spinner /> :
|
||||
<form onSubmit={event => submitFormHandler(event)} id="edit-dns-rec">
|
||||
<input type="hidden" name="save" value="save" />
|
||||
<input type="hidden" name="token" value={token} />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Domain']}
|
||||
value={props.domain}
|
||||
name="v_domain"
|
||||
id="domain"
|
||||
disabled />
|
||||
|
||||
<TextInput
|
||||
value={state.data.rec}
|
||||
title={i18n['Record']}
|
||||
name="v_record_id"
|
||||
id="domain"
|
||||
disabled />
|
||||
|
||||
<SelectInput
|
||||
options={state.selectOptions}
|
||||
selected={state.data.type}
|
||||
title={i18n['Type']}
|
||||
name="v_type"
|
||||
id="type"
|
||||
disabled />
|
||||
|
||||
<TextInput
|
||||
title={i18n['IP or Value']}
|
||||
value={state.data.val}
|
||||
name="v_val"
|
||||
id="val" />
|
||||
|
||||
<TextInput
|
||||
optionalTitle={`(${i18n['optional']})`}
|
||||
value={state.data.priority}
|
||||
title={i18n['Priority']}
|
||||
name="v_priority"
|
||||
id="priority" />
|
||||
|
||||
<TextInput
|
||||
optionalTitle={`(${i18n['internal']})`}
|
||||
title={i18n['Record Number']}
|
||||
value={state.data.record_id}
|
||||
name="v_priority"
|
||||
id="priority" />
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Save}</button>
|
||||
<button type="button" className="back" onClick={() => history.push(`/list/dns?domain=${props.domain}`)}>{i18n.Back}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
}
|
||||
</AddItemLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue