@tasenor/common-plugins 1.10.32 → 1.10.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-ci.log +8 -2
- package/.turbo/turbo-nightly.log +3 -3
- package/.turbo/turbo-nightly3.log +24 -24
- package/dist/GitBackup/backend/index.d.ts +12 -0
- package/dist/GitBackup/backend/index.js +64 -21
- package/dist/GitBackup/backend/index.js.map +1 -1
- package/dist/GitBackup/ui/index.d.ts +2 -0
- package/dist/GitBackup/ui/index.js +36 -11
- package/dist/GitBackup/ui/index.js.map +1 -1
- package/package.json +6 -6
- package/src/GitBackup/backend/index.ts +82 -24
- package/src/GitBackup/ui/index.tsx +60 -12
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-ci.log
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
> @tasenor/common-plugins@1.10.
|
|
2
|
+
> @tasenor/common-plugins@1.10.33 ci /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
3
3
|
> pnpm run lint
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @tasenor/common-plugins@1.10.
|
|
6
|
+
> @tasenor/common-plugins@1.10.33 lint /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
7
7
|
> eslint 'src/**/*.{ts,tsx}' 'data/**/*.mjs'
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
/home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/src/GitBackup/ui/index.tsx
|
|
11
|
+
2:58 warning 'Title' is defined but never used @typescript-eslint/no-unused-vars
|
|
12
|
+
|
|
13
|
+
✖ 1 problem (0 errors, 1 warning)
|
|
14
|
+
|
package/.turbo/turbo-nightly.log
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
> @tasenor/common-plugins@1.10.
|
|
2
|
+
> @tasenor/common-plugins@1.10.33 nightly /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
3
3
|
> pnpm run ci
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @tasenor/common-plugins@1.10.
|
|
6
|
+
> @tasenor/common-plugins@1.10.33 ci /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
7
7
|
> pnpm run lint
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
> @tasenor/common-plugins@1.10.
|
|
10
|
+
> @tasenor/common-plugins@1.10.33 lint /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
11
11
|
> eslint 'src/**/*.{ts,tsx}' 'data/**/*.mjs'
|
|
12
12
|
|
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
|
|
2
|
-
> @tasenor/common-plugins@1.10.
|
|
2
|
+
> @tasenor/common-plugins@1.10.33 nightly3 /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
3
3
|
> pnpm run data
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @tasenor/common-plugins@1.10.
|
|
6
|
+
> @tasenor/common-plugins@1.10.33 data /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
7
7
|
> data/bin/build_all
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishBalanceSheetReportLite.mjs
|
|
11
11
|
|
|
12
|
-
2024-02-
|
|
13
|
-
2024-02-
|
|
12
|
+
2024-02-08T11:36:41.088Z Saved text data to src/FinnishBalanceSheetReportLite/backend/balance-sheet-lite-fi.tsv
|
|
13
|
+
2024-02-08T11:36:41.089Z Saved text data to src/FinnishBalanceSheetReportLite/backend/balance-sheet-lite-en.tsv
|
|
14
14
|
|
|
15
15
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishBalanceSheetReport.mjs
|
|
16
16
|
|
|
17
|
-
2024-02-
|
|
18
|
-
2024-02-
|
|
17
|
+
2024-02-08T11:36:42.277Z Saved text data to src/FinnishBalanceSheetReport/backend/balance-sheet-fi.tsv
|
|
18
|
+
2024-02-08T11:36:42.278Z Saved text data to src/FinnishBalanceSheetReport/backend/balance-sheet-detailed-fi.tsv
|
|
19
19
|
|
|
20
20
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishIncomeStatementReportLite.mjs
|
|
21
21
|
|
|
22
|
-
2024-02-
|
|
23
|
-
2024-02-
|
|
22
|
+
2024-02-08T11:36:43.468Z Saved text data to src/FinnishIncomeStatementReportLite/backend/income-statement-lite-fi.tsv
|
|
23
|
+
2024-02-08T11:36:43.469Z Saved text data to src/FinnishIncomeStatementReportLite/backend/income-statement-lite-en.tsv
|
|
24
24
|
|
|
25
25
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishIncomeStatementReport.mjs
|
|
26
26
|
|
|
27
|
-
2024-02-
|
|
28
|
-
2024-02-
|
|
27
|
+
2024-02-08T11:36:44.685Z Saved text data to src/FinnishIncomeStatementReport/backend/income-statement-fi.tsv
|
|
28
|
+
2024-02-08T11:36:44.686Z Saved text data to src/FinnishIncomeStatementReport/backend/income-statement-detailed-fi.tsv
|
|
29
29
|
|
|
30
30
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishLimitedCompanyComplete.mjs
|
|
31
31
|
|
|
32
|
-
2024-02-
|
|
32
|
+
2024-02-08T11:36:45.868Z Saved data to src/FinnishLimitedCompanyComplete/backend/fi-EUR.tsv
|
|
33
33
|
|
|
34
34
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/FinnishLimitedCompanyLite.mjs
|
|
35
35
|
|
|
36
|
-
2024-02-
|
|
37
|
-
2024-02-
|
|
36
|
+
2024-02-08T11:36:47.091Z Saved data to src/FinnishLimitedCompanyLite/backend/fi-EUR.tsv
|
|
37
|
+
2024-02-08T11:36:47.092Z Saved data to src/FinnishLimitedCompanyLite/backend/en-EUR.tsv
|
|
38
38
|
|
|
39
39
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/IncomeAndExpenses.mjs
|
|
40
40
|
|
|
41
|
-
2024-02-
|
|
42
|
-
2024-02-
|
|
43
|
-
2024-02-
|
|
44
|
-
2024-02-
|
|
45
|
-
2024-02-
|
|
46
|
-
2024-02-
|
|
47
|
-
2024-02-
|
|
48
|
-
2024-02-
|
|
41
|
+
2024-02-08T11:36:48.301Z Saved JSON data to src/IncomeAndExpenses/backend/income.json
|
|
42
|
+
2024-02-08T11:36:48.302Z Saved JSON data to src/IncomeAndExpenses/backend/expense.json
|
|
43
|
+
2024-02-08T11:36:48.303Z Saved JSON data to src/IncomeAndExpenses/backend/assetCodes.json
|
|
44
|
+
2024-02-08T11:36:48.303Z Saved JSON data to src/IncomeAndExpenses/backend/taxTypes.json
|
|
45
|
+
2024-02-08T11:36:48.303Z Refreshed translation data in src/IncomeAndExpenses/backend/index.ts
|
|
46
|
+
2024-02-08T11:36:48.304Z Saved data to ../tasenor-common/src/types/income.ts
|
|
47
|
+
2024-02-08T11:36:48.304Z Saved data to ../tasenor-common/src/types/expense.ts
|
|
48
|
+
2024-02-08T11:36:48.304Z Saved data to ../tasenor-common/src/types/assetCodes.ts
|
|
49
49
|
|
|
50
50
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/PluginIndex.mjs
|
|
51
51
|
|
|
52
|
-
2024-02-
|
|
52
|
+
2024-02-08T11:36:48.890Z Saved plugin index to /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/src/index.ts
|
|
53
53
|
|
|
54
54
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/TickerData.mjs
|
|
55
55
|
|
|
56
|
-
2024-02-
|
|
56
|
+
2024-02-08T11:36:50.186Z Saved JSON data to src/TickerData/backend/currencies.json
|
|
57
57
|
|
|
58
58
|
Running /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins/data/VATFinland.mjs
|
|
59
59
|
|
|
60
|
-
2024-02-
|
|
60
|
+
2024-02-08T11:36:51.414Z Saved JSON data to src/VATFinland/backend/vat.json
|
|
@@ -14,6 +14,18 @@ declare class GitBackup extends ToolPlugin {
|
|
|
14
14
|
* Create manual dump.
|
|
15
15
|
*/
|
|
16
16
|
POST(db: KnexDatabase, data: any): Promise<unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* List of the latest backup commits.
|
|
19
|
+
*/
|
|
20
|
+
GET(db: KnexDatabase, data: any): Promise<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* A helper to check settings and set up repository for further use.
|
|
23
|
+
*/
|
|
24
|
+
private setupRepository;
|
|
25
|
+
/**
|
|
26
|
+
* Get a list of commits.
|
|
27
|
+
*/
|
|
28
|
+
collectCommits(db: KnexDatabase, limit: number): Promise<unknown[]>;
|
|
17
29
|
/**
|
|
18
30
|
* Execute backup making for a database.
|
|
19
31
|
*/
|
|
@@ -7,7 +7,7 @@ class GitBackup extends ToolPlugin {
|
|
|
7
7
|
super();
|
|
8
8
|
this.code = 'GitBackup';
|
|
9
9
|
this.title = 'Backup for Git';
|
|
10
|
-
this.version = '1.0.
|
|
10
|
+
this.version = '1.0.4';
|
|
11
11
|
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></svg>';
|
|
12
12
|
this.releaseDate = '2022-12-12';
|
|
13
13
|
this.use = 'both';
|
|
@@ -40,9 +40,19 @@ class GitBackup extends ToolPlugin {
|
|
|
40
40
|
return { success: false };
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* List of the latest backup commits.
|
|
44
44
|
*/
|
|
45
|
-
async
|
|
45
|
+
async GET(db, data) {
|
|
46
|
+
if (typeof data === 'object' && data !== null && data.type === 'commits') {
|
|
47
|
+
const commits = await this.collectCommits(db, data.count || 10);
|
|
48
|
+
return { success: true, data: { commits } };
|
|
49
|
+
}
|
|
50
|
+
return { success: false };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A helper to check settings and set up repository for further use.
|
|
54
|
+
*/
|
|
55
|
+
async setupRepository(db) {
|
|
46
56
|
const workDir = this.getWorkSpace(db);
|
|
47
57
|
const repository = await this.getSetting(db, 'repository');
|
|
48
58
|
const subDirectory = await this.getSetting(db, 'subDirectory');
|
|
@@ -50,12 +60,14 @@ class GitBackup extends ToolPlugin {
|
|
|
50
60
|
// Skip if not configured for use.
|
|
51
61
|
if (repository === undefined || subDirectory === undefined) {
|
|
52
62
|
error('Cannot make backup since no repository or subdirectory configured.');
|
|
53
|
-
return
|
|
63
|
+
return null;
|
|
54
64
|
}
|
|
65
|
+
// Check repo URL.
|
|
55
66
|
if (!validGitRepoName(repository)) {
|
|
56
67
|
error(`Bad repository address ${JSON.stringify(repository)}.`);
|
|
57
|
-
return
|
|
68
|
+
return null;
|
|
58
69
|
}
|
|
70
|
+
// Set up SSH if needed.
|
|
59
71
|
const sshPath = path.join(workDir, 'ssh.key');
|
|
60
72
|
fs.writeFileSync(sshPath, '');
|
|
61
73
|
fs.chmodSync(sshPath, 0o600);
|
|
@@ -63,28 +75,59 @@ class GitBackup extends ToolPlugin {
|
|
|
63
75
|
fs.appendFileSync(sshPath, sshPrivateKey);
|
|
64
76
|
fs.appendFileSync(sshPath, '\n');
|
|
65
77
|
}
|
|
78
|
+
// Verify the resulting work directory.
|
|
66
79
|
const repoName = GitRepo.defaultName(repository);
|
|
67
80
|
if (!this.isValidWritePath(db, workDir, repoName, subDirectory)) {
|
|
68
81
|
error(`A sub directory '${subDirectory}' does not produce valid allowed work directory for backup in DB '${db.client.config.connection.database}'.`);
|
|
69
|
-
return
|
|
82
|
+
return null;
|
|
70
83
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
const backupDir = path.join(workDir, repoName, subDirectory);
|
|
85
|
+
// Instantiate and configure Git.
|
|
86
|
+
const repo = await GitRepo.get(repository, workDir);
|
|
87
|
+
if (!repo) {
|
|
88
|
+
error(`Failed to establish git repository instance '${repository}' into ${workDir}.`);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
repo.configure({
|
|
92
|
+
name: 'Tasenor',
|
|
93
|
+
email: 'communications.tasenor@gmail.com',
|
|
94
|
+
sshPrivateKey: sshPrivateKey ? sshPath : null,
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
workDir, repository, subDirectory, sshPrivateKey, sshPath, backupDir, repo
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get a list of commits.
|
|
102
|
+
*/
|
|
103
|
+
async collectCommits(db, limit) {
|
|
104
|
+
const setup = await this.setupRepository(db);
|
|
105
|
+
if (!setup) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
const { repo } = setup;
|
|
109
|
+
log(`Fetching commit list for DB '${db.client.config.connection.database}'.`);
|
|
110
|
+
await repo.update();
|
|
111
|
+
const gitLog = await repo.git.log({ maxCount: limit });
|
|
112
|
+
return gitLog.all.map(e => ({
|
|
113
|
+
hash: e.hash,
|
|
114
|
+
date: e.date,
|
|
115
|
+
message: e.message,
|
|
116
|
+
author: `${e.author_name} ${e.author_email ? '<' + e.author_email + '>' : ''}`.trim()
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Execute backup making for a database.
|
|
121
|
+
*/
|
|
122
|
+
async makeBackup(db, message) {
|
|
123
|
+
const setup = await this.setupRepository(db);
|
|
124
|
+
if (!setup) {
|
|
86
125
|
return false;
|
|
87
126
|
}
|
|
127
|
+
const { subDirectory, repo, backupDir } = setup;
|
|
128
|
+
log(`Making a backup into '${subDirectory}' of DB '${db.client.config.connection.database}'.`);
|
|
129
|
+
await this.dump(db, backupDir);
|
|
130
|
+
return repo.put(message, subDirectory);
|
|
88
131
|
}
|
|
89
132
|
/**
|
|
90
133
|
* Write the data from the database to the directory.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/GitBackup/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgB,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtG,OAAO,EAAwB,KAAK,EAAY,GAAG,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/GitBackup/backend/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React, { useState, useRef } from 'react';
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
2
|
import { Note, IconButton, SubPanel, ToolPlugin, Dialog } from '@tasenor/common-ui';
|
|
3
3
|
import { makeObservable, observable, runInAction } from 'mobx';
|
|
4
4
|
import { Trans, useTranslation } from 'react-i18next';
|
|
5
|
-
import { TextField } from '@mui/material';
|
|
5
|
+
import { Box, Table, TableBody, TableCell, TableContainer, TableRow, TextField, Typography } from '@mui/material';
|
|
6
6
|
function MakeBackupIcon(props) {
|
|
7
7
|
const { disabled, onMakeBackup } = props;
|
|
8
8
|
const [askMessage, setAskMessage] = useState(false);
|
|
@@ -14,11 +14,35 @@ function MakeBackupIcon(props) {
|
|
|
14
14
|
React.createElement(TextField, { fullWidth: true, autoFocus: true, value: val.current, onChange: (e) => { setMessage(e.target.value); val.current = e.target.value; } })),
|
|
15
15
|
React.createElement(IconButton, { id: "Make Backup", disabled: disabled, onClick: () => setAskMessage(true), title: "summarize-make-backup", icon: "save" }));
|
|
16
16
|
}
|
|
17
|
+
function BackupCommitList(props) {
|
|
18
|
+
const { store, backups } = props;
|
|
19
|
+
const [commits, setCommits] = useState([]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!store.db) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
store.request(`/db/${store.db}/tools/${GitBackup.code}`, 'GET', { type: 'commits', count: 20 }).then((res) => {
|
|
25
|
+
if (res.success) {
|
|
26
|
+
setCommits(res.data.commits);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}, [store.db, backups]);
|
|
30
|
+
return React.createElement(TableContainer, null,
|
|
31
|
+
React.createElement(Table, null,
|
|
32
|
+
React.createElement(TableBody, null, commits.map((commit, idx) => React.createElement(TableRow, { key: idx },
|
|
33
|
+
React.createElement(TableCell, null,
|
|
34
|
+
React.createElement(Box, null,
|
|
35
|
+
React.createElement(Typography, { color: "secondary" }, commit.hash)),
|
|
36
|
+
React.createElement(Typography, { variant: "body1" }, commit.message),
|
|
37
|
+
React.createElement(Typography, { variant: "caption" }, commit.author)))))));
|
|
38
|
+
}
|
|
17
39
|
class GitBackup extends ToolPlugin {
|
|
18
40
|
busy = false;
|
|
41
|
+
commits = [];
|
|
42
|
+
backups = 0;
|
|
19
43
|
static code = 'GitBackup';
|
|
20
44
|
static title = 'Backup for Git';
|
|
21
|
-
static version = '1.0.
|
|
45
|
+
static version = '1.0.4';
|
|
22
46
|
static icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></svg>';
|
|
23
47
|
static releaseDate = '2022-12-12';
|
|
24
48
|
static use = 'both';
|
|
@@ -27,7 +51,9 @@ class GitBackup extends ToolPlugin {
|
|
|
27
51
|
constructor() {
|
|
28
52
|
super();
|
|
29
53
|
makeObservable(this, {
|
|
30
|
-
busy: observable
|
|
54
|
+
busy: observable,
|
|
55
|
+
commits: observable,
|
|
56
|
+
backups: observable,
|
|
31
57
|
});
|
|
32
58
|
this.languages = {
|
|
33
59
|
// TODO: This is too simple labeling. Need to add plugin code as well.
|
|
@@ -60,6 +86,10 @@ class GitBackup extends ToolPlugin {
|
|
|
60
86
|
const { success } = await this.POST({ makeBackup: message || this.t('Manual backup by GitBackup {version}').replace('{version}', GitBackup.version) });
|
|
61
87
|
runInAction(() => {
|
|
62
88
|
this.busy = false;
|
|
89
|
+
runInAction(() => {
|
|
90
|
+
// Trigger refresh.
|
|
91
|
+
this.backups = this.backups + 1;
|
|
92
|
+
});
|
|
63
93
|
if (success) {
|
|
64
94
|
this.store.addMessage(this.t('Backup created successfully.'));
|
|
65
95
|
}
|
|
@@ -79,19 +109,14 @@ class GitBackup extends ToolPlugin {
|
|
|
79
109
|
React.createElement(Note, null,
|
|
80
110
|
React.createElement(Trans, null, "You need to configure this tool first from the configuration page.")));
|
|
81
111
|
}
|
|
82
|
-
// TODO: Listing and restoring backups.
|
|
83
112
|
return React.createElement(React.Fragment, null,
|
|
84
113
|
React.createElement(SubPanel, null,
|
|
85
114
|
React.createElement(Trans, null, "This tool takes every night automatically one backup."),
|
|
86
115
|
React.createElement(React.Fragment, null, " "),
|
|
87
116
|
React.createElement(Trans, null, "You can also make immediately backup from the icon above."),
|
|
88
117
|
React.createElement(React.Fragment, null, " ")),
|
|
89
|
-
React.createElement(
|
|
90
|
-
React.createElement(
|
|
91
|
-
React.createElement(React.Fragment, null, " "),
|
|
92
|
-
React.createElement(Trans, null, "In order to restore from the backup, you must ensure to get the wanted version as the latest commit in the Git."),
|
|
93
|
-
React.createElement(React.Fragment, null, " "),
|
|
94
|
-
React.createElement(Trans, null, "Then you need to contact support to let them know that DB needs to be loaded from Git.")));
|
|
118
|
+
React.createElement(Box, { sx: { m: 2 } },
|
|
119
|
+
React.createElement(BackupCommitList, { backups: this.backups, store: this.store })));
|
|
95
120
|
}
|
|
96
121
|
getSettings() {
|
|
97
122
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/GitBackup/ui/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/GitBackup/ui/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAS,MAAM,oBAAoB,CAAA;AAC1F,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAQjH,SAAS,cAAc,CAAC,KAA0B;IAChD,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IACxC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA,CAAC,8EAA8E;IAE1G,OAAO;QAEH,oBAAC,MAAM,IACL,KAAK,QACL,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAChD,aAAa,CAAC,KAAK,CAAC,EACtB,SAAS,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAEjD,oBAAC,SAAS,IAAC,SAAS,QAAC,SAAS,QAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA,CAAC,CAAC,GAAG,CAC5H;QAEX,oBAAC,UAAU,IAAC,EAAE,EAAC,aAAa,EAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAC,uBAAuB,EAAC,IAAI,EAAC,MAAM,GAAG,CAChI,CAAA;AACL,CAAC;AAcD,SAAS,gBAAgB,CAAC,KAA4B;IACpD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;IAChC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAkB,EAAE,CAAC,CAAA;IAE3D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;YACb,OAAM;SACP;QACD,KAAK,CAAC,OAAO,CAAiC,OAAO,KAAK,CAAC,EAAE,UAAU,SAAS,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3I,IAAI,GAAG,CAAC,OAAO,EAAE;gBACf,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;aAC7B;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IAEvB,OAAO,oBAAC,cAAc;QACpB,oBAAC,KAAK;YACJ,oBAAC,SAAS,QACP,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,oBAAC,QAAQ,IAAC,GAAG,EAAE,GAAG;gBAC9C,oBAAC,SAAS;oBACR,oBAAC,GAAG;wBAAC,oBAAC,UAAU,IAAC,KAAK,EAAC,WAAW,IAAE,MAAM,CAAC,IAAI,CAAc,CAAM;oBACnE,oBAAC,UAAU,IAAC,OAAO,EAAC,OAAO,IAAE,MAAM,CAAC,OAAO,CAAc;oBACzD,oBAAC,UAAU,IAAC,OAAO,EAAC,SAAS,IAAE,MAAM,CAAC,MAAM,CAAc,CAChD,CACH,CAAC,CACF,CACN,CACO,CAAA;AACnB,CAAC;AAED,MAAM,SAAU,SAAQ,UAAU;IAEhC,IAAI,GAAG,KAAK,CAAA;IACZ,OAAO,GAAG,EAAE,CAAA;IACZ,OAAO,GAAG,CAAC,CAAA;IAEX,MAAM,CAAC,IAAI,GAAG,WAAW,CAAA;IACzB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAA;IAC/B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,MAAM,CAAC,IAAI,GAAG,oTAAoT,CAAA;IAClU,MAAM,CAAC,WAAW,GAAG,YAAY,CAAA;IACjC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAA;IACnB,MAAM,CAAC,IAAI,GAAG,MAAM,CAAA;IACpB,MAAM,CAAC,WAAW,GAAG,qDAAqD,CAAA;IAE1E;QACE,KAAK,EAAE,CAAA;QAEP,cAAc,CAAC,IAAI,EAAE;YACnB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,UAAU;YACnB,OAAO,EAAE,UAAU;SACpB,CAAC,CAAA;QAEF,IAAI,CAAC,SAAS,GAAG;YACf,sEAAsE;YACtE,EAAE,EAAE;gBACF,kBAAkB,EAAE,gBAAgB;gBACpC,oBAAoB,EAAE,oCAAoC;gBAC1D,qBAAqB,EAAE,iBAAiB;gBACxC,4BAA4B,EAAE,eAAe;aAC9C;YACD,EAAE,EAAE;gBACF,kBAAkB,EAAE,gBAAgB;gBACpC,oBAAoB,EAAE,mCAAmC;gBACzD,qBAAqB,EAAE,sBAAsB;gBAC7C,4BAA4B,EAAE,kBAAkB;gBAEhD,gBAAgB,EAAE,gCAAgC;gBAClD,sCAAsC,EAAE,+CAA+C;gBACvF,8BAA8B,EAAE,kCAAkC;gBAClE,yBAAyB,EAAE,uCAAuC;aACnE;SACF,CAAA;IAEH,CAAC;IAED,QAAQ;QACN,OAAO,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,SAAS;QACP,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAA;QACrC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAyB,CAAA;QAC9K,WAAW,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,IAAI,GAAG,KAAK,CAAA;YACjB,WAAW,CAAC,GAAG,EAAE;gBACf,mBAAmB;gBACnB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;YACjC,CAAC,CAAC,CAAA;YACF,IAAI,OAAO,EAAE;gBACX,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAA;aAC9D;iBAAM;gBACL,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAA;aACvD;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QAC1C,OAAO,oBAAC,cAAc,IAAC,QAAQ,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAI,CAAA;IACxG,CAAC;IAED,aAAa;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;gBACL,oBAAC,IAAI;oBAAC,oBAAC,KAAK,6EAA2E,CAAO,CAC7F,CAAA;SACJ;QAED,OAAO;YACL,oBAAC,QAAQ;gBACP,oBAAC,KAAK,gEAA8D;gBAAA,8CAAM;gBAC1E,oBAAC,KAAK,oEAAkE;gBAAA,8CAAM,CACrE;YACX,oBAAC,GAAG,IAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;gBACf,oBAAC,gBAAgB,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CACzD,CACL,CAAA;IACL,CAAC;IAED,WAAW;QACT,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE,EAAE;iBACZ;gBACD;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE;iBACZ;gBACD;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,eAAe;oBACrB,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,EAAE;iBACZ;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,MAAM;oBACb,OAAO,EAAE;wBACP,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE;qBACvD;iBACF;aACF;SACF,CAAA;IACH,CAAC;;AAGH,eAAe,SAAS,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tasenor/common-plugins",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.34",
|
|
4
4
|
"description": "Shared common plugins of Tasenor project",
|
|
5
5
|
"repository": "git@github.com:dataplugoy/tasenor-bookkeeper.git",
|
|
6
6
|
"author": "Tommi Ronkainen <tommi.ronkainen@gmail.com>",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"dayjs": "1.10.8",
|
|
14
14
|
"sprintf-js": "^1.1.2",
|
|
15
15
|
"tsx": "^4.7.0",
|
|
16
|
-
"@tasenor/common": "1.10.
|
|
17
|
-
"@tasenor/common-
|
|
18
|
-
"@tasenor/common-
|
|
16
|
+
"@tasenor/common": "1.10.34",
|
|
17
|
+
"@tasenor/common-node": "1.10.34",
|
|
18
|
+
"@tasenor/common-ui": "1.10.34"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@mui/icons-material": "^5.14.1",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"react-i18next": "^13.0.2",
|
|
32
32
|
"react-router-dom": "^6.14.1",
|
|
33
33
|
"typescript": "^5.1.6",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"@tasenor/config": "1.10.34",
|
|
35
|
+
"eslint-config-tasenor": "0.0.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@mui/icons-material": "^5.14.1",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GitRepo, KnexDatabase, systemPiped, TasenorExporter, ToolPlugin } from '@tasenor/common-node'
|
|
2
|
-
import { DirectoryPath, Email, error, FilePath, log, note, PluginCode, validGitRepoName, Version } from '@tasenor/common'
|
|
2
|
+
import { DirectoryPath, Email, error, FilePath, log, note, PluginCode, Url, validGitRepoName, Version } from '@tasenor/common'
|
|
3
3
|
import fs from 'fs'
|
|
4
4
|
import path from 'path'
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ class GitBackup extends ToolPlugin {
|
|
|
9
9
|
|
|
10
10
|
this.code = 'GitBackup'as PluginCode
|
|
11
11
|
this.title = 'Backup for Git'
|
|
12
|
-
this.version = '1.0.
|
|
12
|
+
this.version = '1.0.4' as Version
|
|
13
13
|
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></svg>'
|
|
14
14
|
this.releaseDate = '2022-12-12'
|
|
15
15
|
this.use = 'both'
|
|
@@ -49,9 +49,28 @@ class GitBackup extends ToolPlugin {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* List of the latest backup commits.
|
|
53
53
|
*/
|
|
54
|
-
async
|
|
54
|
+
async GET(db: KnexDatabase, data): Promise<unknown> {
|
|
55
|
+
if (typeof data === 'object' && data !== null && data.type === 'commits') {
|
|
56
|
+
const commits = await this.collectCommits(db, data.count || 10)
|
|
57
|
+
return { success: true, data: { commits } }
|
|
58
|
+
}
|
|
59
|
+
return { success: false }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A helper to check settings and set up repository for further use.
|
|
64
|
+
*/
|
|
65
|
+
private async setupRepository(db: KnexDatabase): Promise<null | {
|
|
66
|
+
workDir: DirectoryPath,
|
|
67
|
+
repository: Url,
|
|
68
|
+
subDirectory: DirectoryPath,
|
|
69
|
+
sshPrivateKey: string,
|
|
70
|
+
sshPath: FilePath,
|
|
71
|
+
backupDir: DirectoryPath,
|
|
72
|
+
repo: GitRepo,
|
|
73
|
+
}> {
|
|
55
74
|
const workDir = this.getWorkSpace(db)
|
|
56
75
|
const repository = await this.getSetting(db, 'repository')
|
|
57
76
|
const subDirectory = await this.getSetting(db, 'subDirectory')
|
|
@@ -60,14 +79,16 @@ class GitBackup extends ToolPlugin {
|
|
|
60
79
|
// Skip if not configured for use.
|
|
61
80
|
if (repository === undefined || subDirectory === undefined) {
|
|
62
81
|
error('Cannot make backup since no repository or subdirectory configured.')
|
|
63
|
-
return
|
|
82
|
+
return null
|
|
64
83
|
}
|
|
65
84
|
|
|
85
|
+
// Check repo URL.
|
|
66
86
|
if (!validGitRepoName(repository)) {
|
|
67
87
|
error(`Bad repository address ${JSON.stringify(repository)}.`)
|
|
68
|
-
return
|
|
88
|
+
return null
|
|
69
89
|
}
|
|
70
90
|
|
|
91
|
+
// Set up SSH if needed.
|
|
71
92
|
const sshPath: FilePath = path.join(workDir, 'ssh.key') as FilePath
|
|
72
93
|
fs.writeFileSync(sshPath, '')
|
|
73
94
|
fs.chmodSync(sshPath, 0o600)
|
|
@@ -77,31 +98,68 @@ class GitBackup extends ToolPlugin {
|
|
|
77
98
|
fs.appendFileSync(sshPath, '\n')
|
|
78
99
|
}
|
|
79
100
|
|
|
101
|
+
// Verify the resulting work directory.
|
|
80
102
|
const repoName = GitRepo.defaultName(repository)
|
|
81
|
-
|
|
82
103
|
if (!this.isValidWritePath(db, workDir, repoName, subDirectory)) {
|
|
83
104
|
|
|
84
105
|
error(`A sub directory '${subDirectory}' does not produce valid allowed work directory for backup in DB '${db.client.config.connection.database}'.`)
|
|
85
|
-
return
|
|
106
|
+
return null
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const backupDir = path.join(workDir, repoName, subDirectory) as DirectoryPath
|
|
86
110
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
// Instantiate and configure Git.
|
|
112
|
+
const repo = await GitRepo.get(repository, workDir)
|
|
113
|
+
if (!repo) {
|
|
114
|
+
error(`Failed to establish git repository instance '${repository}' into ${workDir}.`)
|
|
115
|
+
return null
|
|
116
|
+
}
|
|
117
|
+
repo.configure({
|
|
118
|
+
name: 'Tasenor',
|
|
119
|
+
email: 'communications.tasenor@gmail.com' as Email,
|
|
120
|
+
sshPrivateKey: sshPrivateKey ? sshPath : null,
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
workDir, repository, subDirectory, sshPrivateKey, sshPath, backupDir, repo
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get a list of commits.
|
|
130
|
+
*/
|
|
131
|
+
async collectCommits(db: KnexDatabase, limit: number): Promise<unknown[]> {
|
|
132
|
+
const setup = await this.setupRepository(db)
|
|
133
|
+
if (!setup) {
|
|
134
|
+
return []
|
|
135
|
+
}
|
|
136
|
+
const { repo } = setup
|
|
137
|
+
|
|
138
|
+
log(`Fetching commit list for DB '${db.client.config.connection.database}'.`)
|
|
139
|
+
await repo.update()
|
|
140
|
+
const gitLog = await repo.git.log({ maxCount: limit })
|
|
141
|
+
return gitLog.all.map(e => ({
|
|
142
|
+
hash: e.hash,
|
|
143
|
+
date: e.date,
|
|
144
|
+
message: e.message,
|
|
145
|
+
author: `${e.author_name} ${e.author_email ? '<' + e.author_email + '>' : ''}`.trim()
|
|
146
|
+
}))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Execute backup making for a database.
|
|
151
|
+
*/
|
|
152
|
+
async makeBackup(db: KnexDatabase, message: string): Promise<boolean> {
|
|
153
|
+
|
|
154
|
+
const setup = await this.setupRepository(db)
|
|
155
|
+
if (!setup) {
|
|
103
156
|
return false
|
|
104
157
|
}
|
|
158
|
+
const { subDirectory, repo, backupDir } = setup
|
|
159
|
+
|
|
160
|
+
log(`Making a backup into '${subDirectory}' of DB '${db.client.config.connection.database}'.`)
|
|
161
|
+
await this.dump(db, backupDir)
|
|
162
|
+
return repo.put(message, subDirectory)
|
|
105
163
|
}
|
|
106
164
|
|
|
107
165
|
/**
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import React, { useState, useRef } from 'react'
|
|
2
|
-
import { Note, IconButton, SubPanel, ToolPlugin, Dialog } from '@tasenor/common-ui'
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import { Note, IconButton, SubPanel, ToolPlugin, Dialog, Title } from '@tasenor/common-ui'
|
|
3
3
|
import { makeObservable, observable, runInAction } from 'mobx'
|
|
4
4
|
import { Trans, useTranslation } from 'react-i18next'
|
|
5
|
-
import { TextField } from '@mui/material'
|
|
5
|
+
import { Box, Table, TableBody, TableCell, TableContainer, TableRow, TextField, Typography } from '@mui/material'
|
|
6
|
+
import { Store, Timestring } from '@tasenor/common'
|
|
6
7
|
|
|
7
8
|
interface MakeBackupIconProps {
|
|
8
9
|
disabled: boolean
|
|
9
10
|
onMakeBackup: (string) => void
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
function MakeBackupIcon(props: MakeBackupIconProps) {
|
|
13
|
+
function MakeBackupIcon(props: MakeBackupIconProps): React.ReactNode {
|
|
13
14
|
const { disabled, onMakeBackup } = props
|
|
14
15
|
const [askMessage, setAskMessage] = useState(false)
|
|
15
16
|
const [message, setMessage] = useState('')
|
|
@@ -30,16 +31,59 @@ function MakeBackupIcon(props: MakeBackupIconProps) {
|
|
|
30
31
|
}
|
|
31
32
|
<IconButton id="Make Backup" disabled={disabled} onClick={() => setAskMessage(true)} title="summarize-make-backup" icon="save" />
|
|
32
33
|
</>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface GitBackupCommit {
|
|
37
|
+
hash: string
|
|
38
|
+
date: Timestring
|
|
39
|
+
message: string
|
|
40
|
+
author: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface BackupCommitListProps {
|
|
44
|
+
store: Store
|
|
45
|
+
backups: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function BackupCommitList(props: BackupCommitListProps): React.ReactNode {
|
|
49
|
+
const { store, backups } = props
|
|
50
|
+
const [commits, setCommits] = useState<GitBackupCommit>([])
|
|
33
51
|
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!store.db) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
store.request<{ commits: GitBackupCommit[] }>(`/db/${store.db}/tools/${GitBackup.code}`, 'GET', { type: 'commits', count: 20 }).then((res) => {
|
|
57
|
+
if (res.success) {
|
|
58
|
+
setCommits(res.data.commits)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}, [store.db, backups])
|
|
62
|
+
|
|
63
|
+
return <TableContainer>
|
|
64
|
+
<Table>
|
|
65
|
+
<TableBody>
|
|
66
|
+
{commits.map((commit, idx) => <TableRow key={idx}>
|
|
67
|
+
<TableCell>
|
|
68
|
+
<Box><Typography color="secondary">{commit.hash}</Typography></Box>
|
|
69
|
+
<Typography variant="body1">{commit.message}</Typography>
|
|
70
|
+
<Typography variant="caption">{commit.author}</Typography>
|
|
71
|
+
</TableCell>
|
|
72
|
+
</TableRow>)}
|
|
73
|
+
</TableBody>
|
|
74
|
+
</Table>
|
|
75
|
+
</TableContainer>
|
|
34
76
|
}
|
|
35
77
|
|
|
36
78
|
class GitBackup extends ToolPlugin {
|
|
37
79
|
|
|
38
80
|
busy = false
|
|
81
|
+
commits = []
|
|
82
|
+
backups = 0
|
|
39
83
|
|
|
40
84
|
static code = 'GitBackup'
|
|
41
85
|
static title = 'Backup for Git'
|
|
42
|
-
static version = '1.0.
|
|
86
|
+
static version = '1.0.4'
|
|
43
87
|
static icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></svg>'
|
|
44
88
|
static releaseDate = '2022-12-12'
|
|
45
89
|
static use = 'both'
|
|
@@ -50,7 +94,9 @@ class GitBackup extends ToolPlugin {
|
|
|
50
94
|
super()
|
|
51
95
|
|
|
52
96
|
makeObservable(this, {
|
|
53
|
-
busy: observable
|
|
97
|
+
busy: observable,
|
|
98
|
+
commits: observable,
|
|
99
|
+
backups: observable,
|
|
54
100
|
})
|
|
55
101
|
|
|
56
102
|
this.languages = {
|
|
@@ -89,6 +135,10 @@ class GitBackup extends ToolPlugin {
|
|
|
89
135
|
const { success } = await this.POST({ makeBackup: message || this.t('Manual backup by GitBackup {version}').replace('{version}', GitBackup.version) }) as { success: boolean }
|
|
90
136
|
runInAction(() => {
|
|
91
137
|
this.busy = false
|
|
138
|
+
runInAction(() => {
|
|
139
|
+
// Trigger refresh.
|
|
140
|
+
this.backups = this.backups + 1
|
|
141
|
+
})
|
|
92
142
|
if (success) {
|
|
93
143
|
this.store.addMessage(this.t('Backup created successfully.'))
|
|
94
144
|
} else {
|
|
@@ -109,17 +159,15 @@ class GitBackup extends ToolPlugin {
|
|
|
109
159
|
<Note><Trans>You need to configure this tool first from the configuration page.</Trans></Note>
|
|
110
160
|
</>
|
|
111
161
|
}
|
|
112
|
-
|
|
162
|
+
|
|
113
163
|
return <>
|
|
114
164
|
<SubPanel>
|
|
115
165
|
<Trans>This tool takes every night automatically one backup.</Trans><> </>
|
|
116
166
|
<Trans>You can also make immediately backup from the icon above.</Trans><> </>
|
|
117
167
|
</SubPanel>
|
|
118
|
-
<
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
<Trans>Then you need to contact support to let them know that DB needs to be loaded from Git.</Trans>
|
|
122
|
-
</SubPanel>
|
|
168
|
+
<Box sx={{ m: 2 }}>
|
|
169
|
+
<BackupCommitList backups={this.backups} store={this.store}/>
|
|
170
|
+
</Box>
|
|
123
171
|
</>
|
|
124
172
|
}
|
|
125
173
|
|