mysqlsyncr 1.0.16 → 1.0.18
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/package.json +1 -1
- package/src/socketServer.js +21 -1
- package/ui/dist/spa/assets/{MainLayout-CGvO4rsY.js → MainLayout-xct47WgG.js} +1 -1
- package/ui/dist/spa/assets/{axios-CrRsmKCW.js → axios-Cl-4MTw5.js} +1 -1
- package/ui/dist/spa/assets/{index-767_aev0.css → index-C3SFaSRt.css} +1 -1
- package/ui/dist/spa/assets/index-i-I_hjUd.js +30 -0
- package/ui/dist/spa/index.html +2 -2
- package/ui/quasar.config.js +2 -1
- package/ui/src/components/FolderBrowser.vue +84 -15
- package/ui/src/pages/MainComponent.vue +50 -32
- package/ui/dist/spa/assets/index-8ohClfZU.js +0 -30
package/ui/dist/spa/index.html
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><title>MySQLsyncr</title><meta charset=utf-8><meta name=description content="A simple ui for the sync features in mysqlsyncr"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png sizes=128x128 href=/icons/favicon-128x128.png><link rel=icon type=image/png sizes=96x96 href=/icons/favicon-96x96.png><link rel=icon type=image/png sizes=32x32 href=/icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/icons/favicon-16x16.png><link rel=icon type=image/ico href=/favicon.ico> <script type="module" crossorigin src="/assets/index-
|
|
2
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
1
|
+
<!DOCTYPE html><html><head><title>MySQLsyncr</title><meta charset=utf-8><meta name=description content="A simple ui for the sync features in mysqlsyncr"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png sizes=128x128 href=/icons/favicon-128x128.png><link rel=icon type=image/png sizes=96x96 href=/icons/favicon-96x96.png><link rel=icon type=image/png sizes=32x32 href=/icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/icons/favicon-16x16.png><link rel=icon type=image/ico href=/favicon.ico> <script type="module" crossorigin src="/assets/index-i-I_hjUd.js"></script>
|
|
2
|
+
<link rel="stylesheet" crossorigin href="/assets/index-C3SFaSRt.css">
|
|
3
3
|
</head><body><div id=q-app></div></body></html>
|
package/ui/quasar.config.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<q-dialog v-model="isOpen" persistent>
|
|
3
3
|
<q-card class="folder-browser-card">
|
|
4
4
|
<q-card-section class="header-section row items-center justify-between">
|
|
5
|
-
<div class="text-h6">Select Folder</div>
|
|
6
|
-
<q-btn icon="close" flat round dense v-close-popup />
|
|
5
|
+
<div class="text-h6 text-white">Select Folder</div>
|
|
6
|
+
<q-btn icon="close" flat round dense v-close-popup class="text-white" />
|
|
7
7
|
</q-card-section>
|
|
8
8
|
|
|
9
9
|
<q-card-section>
|
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
<q-icon name="folder" color="primary" />
|
|
22
22
|
</template>
|
|
23
23
|
</q-input>
|
|
24
|
+
<q-btn
|
|
25
|
+
flat
|
|
26
|
+
color="primary"
|
|
27
|
+
icon="create_new_folder"
|
|
28
|
+
label="New Folder"
|
|
29
|
+
class="q-mt-sm"
|
|
30
|
+
@click="promptNewFolder"
|
|
31
|
+
/>
|
|
24
32
|
</div>
|
|
25
33
|
|
|
26
34
|
<q-list bordered separator class="directory-list">
|
|
@@ -67,6 +75,30 @@
|
|
|
67
75
|
</q-card-actions>
|
|
68
76
|
</q-card>
|
|
69
77
|
</q-dialog>
|
|
78
|
+
|
|
79
|
+
<!-- Add new folder dialog -->
|
|
80
|
+
<q-dialog v-model="newFolderDialog" persistent>
|
|
81
|
+
<q-card style="min-width: 300px">
|
|
82
|
+
<q-card-section class="row items-center">
|
|
83
|
+
<div class="text-h6">Create New Folder</div>
|
|
84
|
+
</q-card-section>
|
|
85
|
+
|
|
86
|
+
<q-card-section>
|
|
87
|
+
<q-input
|
|
88
|
+
v-model="newFolderName"
|
|
89
|
+
label="Folder Name"
|
|
90
|
+
dense
|
|
91
|
+
autofocus
|
|
92
|
+
@keyup.enter="createNewFolder"
|
|
93
|
+
/>
|
|
94
|
+
</q-card-section>
|
|
95
|
+
|
|
96
|
+
<q-card-actions align="right">
|
|
97
|
+
<q-btn flat label="Cancel" color="grey-7" v-close-popup />
|
|
98
|
+
<q-btn flat label="Create" color="primary" @click="createNewFolder" />
|
|
99
|
+
</q-card-actions>
|
|
100
|
+
</q-card>
|
|
101
|
+
</q-dialog>
|
|
70
102
|
</template>
|
|
71
103
|
|
|
72
104
|
<script>
|
|
@@ -87,7 +119,9 @@ export default {
|
|
|
87
119
|
data() {
|
|
88
120
|
return {
|
|
89
121
|
currentPath: '',
|
|
90
|
-
items: []
|
|
122
|
+
items: [],
|
|
123
|
+
newFolderDialog: false,
|
|
124
|
+
newFolderName: ''
|
|
91
125
|
}
|
|
92
126
|
},
|
|
93
127
|
computed: {
|
|
@@ -142,6 +176,38 @@ export default {
|
|
|
142
176
|
if (item.isParent) return 'grey-7';
|
|
143
177
|
if (item.isDirectory) return 'primary';
|
|
144
178
|
return 'grey-6';
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
promptNewFolder() {
|
|
182
|
+
this.newFolderName = '';
|
|
183
|
+
this.newFolderDialog = true;
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
async createNewFolder() {
|
|
187
|
+
if (this.newFolderName.trim()) {
|
|
188
|
+
const newFolderPath = `${this.currentPath}/${this.newFolderName}`;
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
await axios.post('http://localhost:3000/api/create-folder', {
|
|
192
|
+
folderPath: newFolderPath
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Refresh the current directory to show the new folder
|
|
196
|
+
await this.loadFolderContents(this.currentPath);
|
|
197
|
+
this.newFolderDialog = false;
|
|
198
|
+
|
|
199
|
+
this.$q.notify({
|
|
200
|
+
type: 'positive',
|
|
201
|
+
message: 'Folder created successfully'
|
|
202
|
+
});
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.error('Error creating folder:', error);
|
|
205
|
+
this.$q.notify({
|
|
206
|
+
type: 'negative',
|
|
207
|
+
message: 'Error creating folder'
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
145
211
|
}
|
|
146
212
|
},
|
|
147
213
|
async mounted() {
|
|
@@ -152,43 +218,46 @@ export default {
|
|
|
152
218
|
|
|
153
219
|
<style scoped>
|
|
154
220
|
.folder-browser-card {
|
|
155
|
-
min-width:
|
|
156
|
-
max-width:
|
|
157
|
-
border-radius:
|
|
158
|
-
box-shadow: 0 4px
|
|
221
|
+
min-width: 600px;
|
|
222
|
+
max-width: 900px;
|
|
223
|
+
border-radius: 4px;
|
|
224
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
159
225
|
}
|
|
160
226
|
|
|
161
227
|
.header-section {
|
|
162
|
-
background-color:
|
|
163
|
-
border-bottom: 1px solid
|
|
164
|
-
padding:
|
|
228
|
+
background-color: var(--q-primary);
|
|
229
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
230
|
+
padding: 16px 20px;
|
|
165
231
|
}
|
|
166
232
|
|
|
167
233
|
.path-section {
|
|
168
|
-
margin-bottom:
|
|
234
|
+
margin-bottom: 16px;
|
|
169
235
|
}
|
|
170
236
|
|
|
171
237
|
.current-path-input {
|
|
172
238
|
font-family: monospace;
|
|
239
|
+
font-size: 13px;
|
|
173
240
|
}
|
|
174
241
|
|
|
175
242
|
.directory-list {
|
|
176
|
-
max-height:
|
|
243
|
+
max-height: 450px;
|
|
177
244
|
overflow-y: auto;
|
|
178
245
|
border-radius: 4px;
|
|
179
246
|
border: 1px solid #e0e0e0;
|
|
180
247
|
}
|
|
181
248
|
|
|
182
249
|
.directory-item {
|
|
183
|
-
transition: background-color 0.
|
|
250
|
+
transition: background-color 0.15s;
|
|
251
|
+
min-height: 40px;
|
|
184
252
|
}
|
|
185
253
|
|
|
186
254
|
.directory-item:hover {
|
|
187
|
-
background-color: #
|
|
255
|
+
background-color: #f5f9ff;
|
|
188
256
|
}
|
|
189
257
|
|
|
190
258
|
.action-buttons {
|
|
191
|
-
padding:
|
|
259
|
+
padding: 12px 20px;
|
|
192
260
|
border-top: 1px solid #e0e0e0;
|
|
261
|
+
background-color: #fafafa;
|
|
193
262
|
}
|
|
194
263
|
</style>
|
|
@@ -802,54 +802,72 @@ export default {
|
|
|
802
802
|
}).onOk(async () => {
|
|
803
803
|
console.log('Overwriting existing dump')
|
|
804
804
|
await this.createNewDump(false)
|
|
805
|
+
await this.getDatabasesFromExistingDumps()
|
|
806
|
+
await this.fetchAllDifferences()
|
|
805
807
|
})
|
|
806
808
|
return
|
|
807
809
|
}
|
|
808
810
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
+
this.$q.loading.show({
|
|
812
|
+
message: 'Creating new dump...',
|
|
813
|
+
spinnerColor: 'primary',
|
|
814
|
+
backgroundColor: 'grey-1',
|
|
815
|
+
spinnerSize: 80,
|
|
816
|
+
messageColor: 'primary',
|
|
817
|
+
customClass: 'custom-loading',
|
|
818
|
+
})
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
|
|
822
|
+
let response = await axios.post('http://localhost:3000/api/dump', {
|
|
811
823
|
config: {
|
|
812
824
|
host: this.host,
|
|
813
825
|
port: this.port,
|
|
814
826
|
user: this.user,
|
|
815
827
|
password: this.password,
|
|
816
828
|
output: this.dbFolder,
|
|
817
|
-
// database: this.database,
|
|
818
829
|
},
|
|
819
830
|
})
|
|
820
|
-
.catch((error) => {
|
|
821
|
-
if (error.response.data.message) {
|
|
822
|
-
this.$q.dialog({
|
|
823
|
-
title: 'Error',
|
|
824
|
-
message: error.response.data.message,
|
|
825
|
-
})
|
|
826
|
-
}
|
|
827
|
-
console.error('Error creating new dump:', error)
|
|
828
|
-
return
|
|
829
|
-
})
|
|
830
831
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
832
|
+
if (response.data.message) {
|
|
833
|
+
this.$q.notify({
|
|
834
|
+
type: 'positive',
|
|
835
|
+
message: response.data.message,
|
|
836
|
+
position: 'top'
|
|
837
|
+
})
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Update loading message for each subsequent operation
|
|
841
|
+
this.$q.loading.show({
|
|
842
|
+
message: 'Loading databases...',
|
|
843
|
+
spinnerColor: 'primary',
|
|
844
|
+
backgroundColor: 'grey-1',
|
|
845
|
+
spinnerSize: 80,
|
|
846
|
+
messageColor: 'primary',
|
|
847
|
+
customClass: 'custom-loading',
|
|
836
848
|
})
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
+
await this.getDatabasesFromExistingDumps()
|
|
850
|
+
|
|
851
|
+
this.$q.loading.show({
|
|
852
|
+
message: 'Fetching differences...',
|
|
853
|
+
spinnerColor: 'primary',
|
|
854
|
+
backgroundColor: 'grey-1',
|
|
855
|
+
spinnerSize: 80,
|
|
856
|
+
messageColor: 'primary',
|
|
857
|
+
customClass: 'custom-loading',
|
|
858
|
+
})
|
|
859
|
+
await this.fetchAllDifferences()
|
|
860
|
+
|
|
861
|
+
} catch (error) {
|
|
862
|
+
this.$q.loading.hide()
|
|
849
863
|
this.$q.notify({
|
|
850
|
-
|
|
851
|
-
|
|
864
|
+
type: 'negative',
|
|
865
|
+
message: error.response?.data?.message || 'Error creating dump',
|
|
866
|
+
position: 'top'
|
|
852
867
|
})
|
|
868
|
+
console.error('Error creating new dump:', error)
|
|
869
|
+
} finally {
|
|
870
|
+
this.$q.loading.hide()
|
|
853
871
|
}
|
|
854
872
|
},
|
|
855
873
|
showIssueDetails(issue, node) {
|