#114 / #117 Save history

This commit is contained in:
Keith Paterson 2021-01-14 22:27:42 +01:00
parent fbf0e5cbab
commit bcc5bbb335
8 changed files with 373 additions and 193 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "flightgear-airports", "name": "flightgear-airports",
"version": "0.0.27", "version": "0.0.28",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -92,7 +92,7 @@
"coordinate-parser": "^1.0.3", "coordinate-parser": "^1.0.3",
"dijkstrajs": "^1.0.1", "dijkstrajs": "^1.0.1",
"electron-debug": "^3.0.1", "electron-debug": "^3.0.1",
"element-ui": "^2.13.2", "element-ui": "^2.14.1",
"file-url": "^3.0.0", "file-url": "^3.0.0",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",

View File

@ -11,32 +11,84 @@ You should have received a copy of the GNU General Public License along with FG
--> -->
<template> <template>
<div id="EditBar"> <div id="EditBar">
<ZoomButton icon="fas fa-th" v-on:click="zoomin" :show="true" tooltip="Zoomin"></ZoomButton>
<ZoomButton icon="fas fa-th-large" v-on:click="zoomout" :show="!editing" tooltip="Zoomout"></ZoomButton>
<!--<ZoomButton icon="far fa-eye-slash" v-on:click="hideAPT" :show='true' tooltip="Hide APT"></ZoomButton>-->
<!--<EditButton icon="fas fa-upload" v-on:click="upload" :show="!editing" tooltip="Upload"></EditButton>--> <el-dialog
<!--<EditButton icon="fas fa-edit" v-on:click="edit" :show="!editing" tooltip="Edit"></EditButton>--> title="Checking"
<EditButton width="30%"
icon="fas fa-undo" center
v-on:click="centerDialogVisible = true" :visible.sync="checkDialogVisible"
:show="editing" >
tooltip="Undo" <el-container direction="vertical">
></EditButton> <el-progress
<el-dialog title="Reload" :visible.sync="centerDialogVisible" width="30%" center> :percentage="Number(((progress / max) * 100).toPrecision(3))"
<span style="center">Reload from last save? You will lose the current edits.</span> v-if="max > 0"
></el-progress>
</el-container>
</el-dialog>
<el-dialog
title="Revert"
:visible.sync="centerDialogVisible"
width="550px"
center
>
<span>
Please select the Version to revert to.
<el-row v-for="item in saves" :key="item.file">
<el-button @click="revert(item.file)">{{item.mtime}}</el-button>
</el-row>
</span>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="undoFirst">Base version (GIT)</el-button> <el-button type="primary" @click="cancel">Cancel</el-button>
<el-button type="primary" @click="undoLast">Last save</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="Saving" :visible.sync="saveDialogVisible" width="30%" center> <el-dialog
title="Saving"
:visible.sync="saveDialogVisible"
width="30%"
center
>
<span style="center">Saving..</span> <span style="center">Saving..</span>
</el-dialog> </el-dialog>
<EditButton icon="fas fa-save" v-on:click="save" :show="editing" tooltip="Save"></EditButton> <ZoomButton
<EditButton icon="far fa-check-square" v-on:click="showCheck" :show="editing" tooltip="Check"></EditButton> icon="fas fa-th"
v-on:click="zoomin"
:show="true"
tooltip="Zoomin"
></ZoomButton>
<ZoomButton
icon="fas fa-th-large"
v-on:click="zoomout"
:show="!editing"
tooltip="Zoomout"
></ZoomButton>
<EditButton
icon="fa fa-window-close"
v-on:click="close"
:show="editing"
tooltip="Close/Save Editing"
></EditButton>
<EditButton
icon="fas fa-undo"
v-on:click="openReload"
:show="editing"
tooltip="Revert to Savepoint"
></EditButton>
<EditButton
icon="fas fa-save"
v-on:click="save"
:show="editing"
tooltip="Save"
></EditButton>
<EditButton
icon="far fa-check-square"
v-on:click="showCheck"
:show="editing"
tooltip="Check"
></EditButton>
<EditButton <EditButton
icon="fas fa-draw-polygon" icon="fas fa-draw-polygon"
v-on:click="drawPolyline" v-on:click="drawPolyline"
@ -61,12 +113,12 @@ You should have received a copy of the GNU General Public License along with FG
:show="editing" :show="editing"
tooltip="Draw Parking" tooltip="Draw Parking"
></EditButton> ></EditButton>
<EditButton icon="fas fa-trash-alt" v-on:click="deleteFeature" :show="editing" tooltip="Remove"></EditButton> <EditButton
<el-dialog title="Checking" width="30%" center :visible.sync="checkDialogVisible"> icon="fas fa-trash-alt"
<el-container direction="vertical"> v-on:click="deleteFeature"
<el-progress :percentage="Number(((progress / max)*100).toPrecision(3))" v-if="max>0"></el-progress> :show="editing"
</el-container> tooltip="Remove"
</el-dialog> ></EditButton>
</div> </div>
</template> </template>
@ -76,6 +128,8 @@ You should have received a copy of the GNU General Public License along with FG
const fs = require('fs'); const fs = require('fs');
const mapper = require('../check/mapper'); const mapper = require('../check/mapper');
import {listSaves} from '../loaders/groundnet_loader'
import EditButton from './EditButton' import EditButton from './EditButton'
import ZoomButton from './ZoomButton'; import ZoomButton from './ZoomButton';
import Vue from 'vue' import Vue from 'vue'
@ -85,11 +139,14 @@ You should have received a copy of the GNU General Public License along with FG
export default { export default {
components: { EditButton, ZoomButton }, components: { EditButton, ZoomButton },
data () { data () {
return {isEditing: false, uploadVisible: false, centerDialogVisible: false, saveDialogVisible: false, checkDialogVisible: false, checking: false, progress: 0, max: 0, pavementLayerVisible: true} return {isEditing: false, uploadVisible: false, centerDialogVisible: false, saveDialogVisible: false, checkDialogVisible: false, checking: false, progress: 0, max: 0, pavementLayerVisible: true, saves: [] }
}, },
created () { created () {
}, },
methods: { methods: {
cancel () {
this.centerDialogVisible = false
},
zoomout() { zoomout() {
this.$parent.$parent.$refs.editLayer.stopDrawing() this.$parent.$parent.$refs.editLayer.stopDrawing()
this.$parent.$parent.zoomUpdated(9) this.$parent.$parent.zoomUpdated(9)
@ -109,7 +166,7 @@ You should have received a copy of the GNU General Public License along with FG
setEditing (editing) { setEditing (editing) {
this.isEditing = editing this.isEditing = editing
}, },
undoFirst () { revert (file) {
this.isEditing = false this.isEditing = false
this.$emit('edit', false) this.$emit('edit', false)
this.centerDialogVisible = false this.centerDialogVisible = false
@ -117,25 +174,32 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.$parent.$refs.editLayer.disableEdit() this.$parent.$parent.$refs.editLayer.disableEdit()
this.$parent.$parent.$refs.towerLayer.disableEdit() this.$parent.$parent.$refs.towerLayer.disableEdit()
this.$parent.$parent.$refs.thresholdLayer.disableEdit() this.$parent.$parent.$refs.thresholdLayer.disableEdit()
this.$parent.$parent.$refs.editLayer.reload(true) this.$parent.$parent.$refs.editLayer.reload(file)
}, },
undoLast () { close () {
this.isEditing = false
this.$emit('edit', false)
this.centerDialogVisible = false
this.$parent.$parent.$refs.map.mapObject.options.minZoom = 1;
this.$parent.$parent.$refs.editLayer.disableEdit()
this.$parent.$parent.$refs.towerLayer.disableEdit()
this.$parent.$parent.$refs.thresholdLayer.disableEdit()
this.$parent.$parent.$refs.editLayer.reload(false)
},
save () {
this.$parent.$parent.$refs.editLayer.stopDrawing() this.$parent.$parent.$refs.editLayer.stopDrawing()
this.isEditing = false this.isEditing = false
this.$emit('edit', false) this.$emit('edit', false)
this.$parent.$parent.$refs.map.mapObject.options.minZoom = 1; this.$parent.$parent.$refs.map.mapObject.options.minZoom = 1;
Vue.set(this, 'saveDialogVisible', true) Vue.set(this, 'saveDialogVisible', true)
this.$emit('edit', false) this.$emit('edit', false)
Vue.nextTick( function () {
setTimeout( this.closeDefered.bind(this), 100);
}, this)
},
closeDefered () {
this.$parent.$parent.$refs.editLayer.save()
this.$parent.$parent.$refs.towerLayer.save()
this.$parent.$parent.$refs.thresholdLayer.save()
this.$parent.$parent.$refs.editLayer.disableEdit()
this.$parent.$parent.$refs.towerLayer.disableEdit()
this.$parent.$parent.$refs.thresholdLayer.disableEdit()
this.rescanCurrentGroundnet()
Vue.set(this, 'saveDialogVisible', false)
},
save () {
Vue.set(this, 'saveDialogVisible', true)
this.$parent.$parent.$refs.editLayer.stopDrawing()
Vue.nextTick( function () { Vue.nextTick( function () {
setTimeout( this.saveDefered.bind(this), 100); setTimeout( this.saveDefered.bind(this), 100);
}, this) }, this)
@ -144,13 +208,10 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.$parent.$refs.editLayer.save() this.$parent.$parent.$refs.editLayer.save()
this.$parent.$parent.$refs.towerLayer.save() this.$parent.$parent.$refs.towerLayer.save()
this.$parent.$parent.$refs.thresholdLayer.save() this.$parent.$parent.$refs.thresholdLayer.save()
this.$parent.$parent.$refs.editLayer.disableEdit() this.rescanCurrentGroundnet()
this.$parent.$parent.$refs.towerLayer.disableEdit()
this.$parent.$parent.$refs.thresholdLayer.disableEdit()
this.scanGroundnets()
Vue.set(this, 'saveDialogVisible', false) Vue.set(this, 'saveDialogVisible', false)
}, },
scanGroundnets () { rescanCurrentGroundnet () {
try { try {
const winURL = process.env.NODE_ENV === 'development' const winURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080/src/renderer/utils/worker.js` ? `http://localhost:9080/src/renderer/utils/worker.js`
@ -297,6 +358,13 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.$parent.$refs.editLayer.stopDrawing() this.$parent.$parent.$refs.editLayer.stopDrawing()
Vue.set(this, 'checkDialogVisible', true) Vue.set(this, 'checkDialogVisible', true)
this.check() this.check()
},
openReload: function() {
this.centerDialogVisible = true
var icao = this.$parent.$parent.$refs.editLayer.icao
if (icao !== undefined && icao !== '') {
this.saves = listSaves(this.$store.state.Settings.settings.airportsDirectory, icao).sort((a, b) => a.mtimeMs - b.mtimeMs)
}
} }
}, },
computed: { computed: {

View File

@ -109,7 +109,7 @@ You should have received a copy of the GNU General Public License along with FG
}, },
data () { data () {
return { return {
maxId: 1, icao: String, checking: false, editing: false maxId: 1, icao: '', checking: false, editing: false
} }
}, },
methods: { methods: {
@ -128,13 +128,18 @@ You should have received a copy of the GNU General Public License along with FG
this.selection = parkings; this.selection = parkings;
return parkings; return parkings;
}, },
load (icao, force) { load (icao, filename) {
if (this.groundnetLayerGroup !== undefined) { if (this.groundnetLayerGroup !== undefined) {
this.groundnetLayerGroup.removeFrom(this.$parent.mapObject) this.groundnetLayerGroup.removeFrom(this.$parent.mapObject)
} }
this.$parent.$parent.setIcao(icao) this.$parent.$parent.setIcao(icao)
this.icao = icao this.icao = icao
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao, force) var f = path.join(this.$store.state.Settings.settings.airportsDirectory, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
if (!fs.existsSync(f)) {
f = path.join(this.$store.state.Settings.settings.airportsDirectory, icao[0], icao[1], icao[2], icao + '.groundnet.xml');
}
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao, f)
if (this.groundnetLayerGroup === undefined) { if (this.groundnetLayerGroup === undefined) {
console.warn('Groundnet for ICAO not loaded ' + icao) console.warn('Groundnet for ICAO not loaded ' + icao)
return return
@ -912,8 +917,8 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.mapObject.off('click', this.addParking) this.$parent.mapObject.off('click', this.addParking)
this.$parent.mapObject._container.style.cursor = '' this.$parent.mapObject._container.style.cursor = ''
}, },
reload (force) { reload (filename) {
this.load(this.icao, force) this.load(this.icao, filename)
}, },
link (index) { link (index) {
var layers = [] var layers = []
@ -1007,8 +1012,7 @@ You should have received a copy of the GNU General Public License along with FG
//console.debug(l) //console.debug(l)
xml.push(l) xml.push(l)
}) })
writeGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, this.icao, xml) writeGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, this.icao, xml)
this.load(this.icao, false)
}, },
//Copy to test directory //Copy to test directory
test() { test() {

View File

@ -6,135 +6,206 @@
<i class="fa fa-caret-left"></i> <i class="fa fa-caret-left"></i>
</div> </div>
</h1> </h1>
<div id="panel" width="100%"> <el-collapse v-model="activeName" accordion>
<el-row> <el-collapse-item title="General" name="1">
<el-col :span="22" class="label">Airports Directory</el-col> <el-row>
</el-row> <el-col :span="12" class="label">Number of saves : </el-col>
<el-row> <el-col :span="12">
<el-col :span="22" v-bind:class="{ invalid: !airports_directory_ok, file_label: airports_directory_ok}">{{ airports_directory }}</el-col> <el-popover
<el-col :span="2"> placement="top-start"
<el-popover title="Saves"
placement="top-start" width="200"
title="E-Mail" trigger="hover"
width="200" content="How many previous versions should be kept."
trigger="hover" >
content="The work directory. Best is a copy from groundweb" <el-input
placeholder="Number of versions"
slot="reference"
v-model="numberOfSaves"
></el-input>
</el-popover>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="Directories" name="2">
<el-row>
<el-col :span="22" class="label">Airports Directory</el-col>
</el-row>
<el-row>
<el-col
:span="22"
v-bind:class="{
invalid: !airports_directory_ok,
file_label: airports_directory_ok,
}"
>{{ airports_directory }}</el-col
> >
<directory-select @input="airportsDirectorySelect" slot="reference"></directory-select> <el-col :span="2">
</el-popover> <el-popover
</el-col> placement="top-start"
</el-row> title="E-Mail"
<el-row> width="200"
<el-col :span="22" class="label">Flightgear Data Directory</el-col> trigger="hover"
</el-row> content="The work directory. Best is a copy from groundweb"
<el-row> >
<el-col :span="22" v-bind:class="{ invalid: !flightgear_directory_ok, file_label: flightgear_directory_ok}">{{ flightgear_directory }}</el-col> <directory-select
<el-col :span="2"> @input="airportsDirectorySelect"
<el-popover slot="reference"
placement="top-start" ></directory-select>
title="E-Mail" </el-popover>
width="200" </el-col>
trigger="hover" </el-row>
content="The FGDATA directory." <el-row>
> <el-col :span="22" class="label">Flightgear Data Directory</el-col>
<directory-select @input="flightgearDirectorySelect" slot="reference"></directory-select> </el-row>
</el-popover> <el-row>
</el-col> <el-col
</el-row> :span="22"
<el-row> v-bind:class="{
<el-col :span="22" class="label">Traffic Directory</el-col> invalid: !flightgear_directory_ok,
</el-row> file_label: flightgear_directory_ok,
<el-row> }"
<el-col :span="22" v-bind:class="{ invalid: !Traffic_directory_ok, file_label: Traffic_directory_ok}">{{ Traffic_directory }}</el-col> >{{ flightgear_directory }}</el-col
<el-col :span="2">
</el-col>
</el-row>
<el-row>
<el-col :span="22" class="label">APT File</el-col>
</el-row>
<el-row>
<el-col :span="22" v-bind:class="{invalid: !apt_file_ok}" >{{ apt_file }}</el-col>
<el-col :span="2">
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Export Directory</el-col>
<el-col :span="15" v-bind:class="{invalid: !test_directory_ok, file_label: test_directory_ok}">{{ test_directory }}</el-col>
<el-col :span="2">
<directory-select @input="testDirectorySelect"></directory-select>
</el-col>
</el-row>
<el-row>
<el-col :span="22" class="label">Phi Host Url</el-col>
</el-row>
<el-row>
<el-col :span="24" class="label">
<el-input placeholder="Please input a valid Phi URL" v-model="phi_url"></el-input>
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Author E-Mail : </el-col>
<el-col :span="17">
<el-popover
placement="top-start"
title="E-Mail"
width="200"
trigger="hover"
content="Only used as a committer/author for Github. This e-mail is only visible via GIT."
>
<el-input placeholder="Please input your email" slot="reference" v-model="email"></el-input>
</el-popover>
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Author Name : </el-col>
<el-col :span="17">
<el-popover
placement="top-start"
title="Goto"
width="200"
trigger="hover"
content="This is saved to the file and is therefore distributed via Terrasync."
>
<el-input placeholder="Please input your Name" slot="reference" v-model="name"></el-input>
</el-popover>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<span class="label">Scan logging :</span>
</el-col>
<el-col :span="15">
<el-popover
placement="top-start"
title="Logging"
width="200"
trigger="hover"
content="Switch on logging for scan. Big performance hit"
> >
<el-switch v-model="scanLogging" slot="reference"></el-switch> <el-col :span="2">
</el-popover> <el-popover
</el-col> placement="top-start"
</el-row> title="E-Mail"
<el-row> width="200"
<el-col :span="7" class="label"></el-col> trigger="hover"
<el-col :span="17"> content="The FGDATA directory."
<el-popover >
placement="top-start" <directory-select
title="Debug" @input="flightgearDirectorySelect"
width="200" slot="reference"
trigger="hover" ></directory-select>
content="Opens the JavaScript Debugger for troubleshooting" </el-popover>
> </el-col>
<el-button @click="debug" class="button" slot="reference" > </el-row>
<i class="fas fa-bug"></i> Debugger <el-row>
</el-button> <el-col :span="22" class="label">Traffic Directory</el-col>
</el-popover> </el-row>
</el-col> <el-row>
</el-row> <el-col
</div> :span="22"
v-bind:class="{
invalid: !Traffic_directory_ok,
file_label: Traffic_directory_ok,
}"
>{{ Traffic_directory }}</el-col
>
<el-col :span="2"> </el-col>
</el-row>
<el-row>
<el-col :span="22" class="label">APT File</el-col>
</el-row>
<el-row>
<el-col :span="22" v-bind:class="{ invalid: !apt_file_ok }">{{
apt_file
}}</el-col>
<el-col :span="2"> </el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Export Directory : </el-col>
<el-col
:span="15"
v-bind:class="{
invalid: !test_directory_ok,
file_label: test_directory_ok,
}"
>{{ test_directory }}</el-col
>
<el-col :span="2">
<directory-select @input="testDirectorySelect"></directory-select>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="User" name="3">
<el-row>
<el-col :span="7" class="label">Author E-Mail : </el-col>
<el-col :span="17">
<el-popover
placement="top-start"
title="E-Mail"
width="200"
trigger="hover"
content="Only used as a committer/author for Github. This e-mail is only visible via GIT."
>
<el-input
placeholder="Please input your email"
slot="reference"
v-model="email"
></el-input>
</el-popover>
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Author Name : </el-col>
<el-col :span="17">
<el-popover
placement="top-start"
title="Goto"
width="200"
trigger="hover"
content="This is saved to the file and is therefore distributed via Terrasync."
>
<el-input
placeholder="Please input your Name"
slot="reference"
v-model="name"
></el-input>
</el-popover>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="Troubleshooting" name="4">
<el-row>
<el-col :span="7">
<span class="label">Scan logging :</span>
</el-col>
<el-col :span="15">
<el-popover
placement="top-start"
title="Logging"
width="200"
trigger="hover"
content="Switch on logging for scan. Big performance hit"
>
<el-switch v-model="scanLogging" slot="reference"></el-switch>
</el-popover>
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label"></el-col>
<el-col :span="17">
<el-popover
placement="top-start"
title="Debug"
width="200"
trigger="hover"
content="Opens the JavaScript Debugger for troubleshooting"
>
<el-button @click="debug" class="button" slot="reference">
<i class="fas fa-bug"></i> Debugger
</el-button>
</el-popover>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="Flightgear" name="5">
<el-row>
<el-col :span="22" class="label">Phi Host Url</el-col>
</el-row>
<el-row>
<el-col :span="24" class="label">
<el-input
placeholder="Please input a valid Phi URL"
v-model="phi_url"
></el-input>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
</div> </div>
</template> </template>
@ -152,8 +223,7 @@
}, },
data () { data () {
return { ok: true return { ok: true, activeName: '0' }
}
}, },
methods: { methods: {
flightgearDirectorySelect: function (flightgearDirectory) { flightgearDirectorySelect: function (flightgearDirectory) {
@ -173,6 +243,16 @@
} }
}, },
computed: { computed: {
numberOfSaves: {
// getter
get: function () {
return this.$store.state.Settings.settings.numberOfSaves
},
// setter
set: function (newValue) {
this.$store.commit('SET_NUMBER_OF_SAVES', newValue)
}
},
email: { email: {
// getter // getter
get: function () { get: function () {
@ -293,5 +373,4 @@
padding: 5px; padding: 5px;
background-color: red; background-color: red;
} }
</style> </style>

View File

@ -29,22 +29,37 @@ function addFrequencies (type, value) {
} }
exports.addFeature = function (feature) { exports.addFeature = function (feature) {
featureLookup[feature.id] = new Array(); featureLookup[feature.id] = [];
} }
exports.readGroundnetXML = function (fDir, icao, force) { exports.listSaves = function (fDir, icao) {
var directory = path.join(fDir, icao[0], icao[1], icao[2]);
var files = fs.readdirSync(directory);
var ret = files
.filter(f => f.includes(icao) )
.filter(f => f.includes('groundnet') )
.map(f => {
try {
var fileDate = fs.lstatSync(path.join(directory, f));
return {file: f, mtime: `${fileDate.mtime}`, mtimeMs: `${fileDate.mtimeMs}`};
} catch (error) {
console.error(error);
}
});
ret.forEach( f => {
console.debug(f);
});
return ret;
}
exports.readGroundnetXML = function (fDir, icao, f) {
try { try {
store.default.dispatch('setGroundnetLoaded', false); store.default.dispatch('setGroundnetLoaded', false);
var layerGroup = L.layerGroup(); var layerGroup = L.layerGroup();
layerGroup.maxId = 0; layerGroup.maxId = 0;
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.xml');
var fNew = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
if (f == null || (!fs.existsSync(f) && force)|| (!fs.existsSync(f) && !fs.existsSync(fNew) )) if (f == null || (!fs.existsSync(f) ))
return layerGroup; return layerGroup;
if (fNew != null && fs.existsSync(fNew) && !force) {
f = fNew;
}
var features = new Array(); var features = new Array();

View File

@ -65,11 +65,22 @@ exports.writeGroundnetXML = function (fDir, icao, featureList) {
try { fs.mkdirSync(path.join(fDir, icao[0], icao[1]), { recursive: true })} catch (err) { } try { fs.mkdirSync(path.join(fDir, icao[0], icao[1]), { recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(fDir, icao[0], icao[1], icao[2]), { recursive: true })} catch (err) { } try { fs.mkdirSync(path.join(fDir, icao[0], icao[1], icao[2]), { recursive: true })} catch (err) { }
var fileNames = [];
for (let index = 1; index <= store.default.state.Settings.settings.numberOfSaves; index++) {
fileNames.push(path.join(fDir, icao[0], icao[1], icao[2], icao + `.groundnet.bak.${index}.xml`));
}
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml'); var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
var fBak = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.bak.xml');
if( fs.existsSync(f) ) { if( fs.existsSync(f) ) {
fs.copyFileSync(f, fBak); var previous = '';
fileNames.reverse().forEach(fBak => {
if (fs.existsSync(fBak) && previous !== '') {
console.debug( `Copy ${fBak} to ${previous}`);
fs.copyFileSync(fBak, previous);
}
previous = fBak;
});
fs.copyFileSync(f, previous);
} }
if (f == null) if (f == null)
return; return;

View File

@ -3,7 +3,7 @@ const path = require('path');
const fs = require('fs'); const fs = require('fs');
const state = { const state = {
settings: { flightgearDirectory: '.', testDirectory: '.', email: 'flightgearairports@example.org', name: 'unknown', phi_url: 'http://localhost:8080' }, settings: { numberOfSaves: 1, flightgearDirectory: '.', testDirectory: '.', email: 'flightgearairports@example.org', name: 'unknown', phi_url: 'http://localhost:8080' },
zoom: 14, zoom: 14,
center: [47.413220, -1.219482], center: [47.413220, -1.219482],
bounds: undefined, bounds: undefined,
@ -50,6 +50,9 @@ const mutations = {
'SET_NAME'(state, name) { 'SET_NAME'(state, name) {
state.settings.name = name state.settings.name = name
}, },
'SET_NUMBER_OF_SAVES'(state, numberOfSaves) {
state.settings.numberOfSaves = numberOfSaves
},
'SET_PHI_URL'(state, phi_url) { 'SET_PHI_URL'(state, phi_url) {
state.settings.phi_url = phi_url state.settings.phi_url = phi_url
}, },