2020-08-08 23:59:13 +02:00
|
|
|
|
<template>
|
|
|
|
|
|
<v-container fluid>
|
2020-09-30 20:04:35 +02:00
|
|
|
|
<v-card>
|
|
|
|
|
|
<v-card-title>
|
|
|
|
|
|
<v-toolbar flat>
|
2020-10-02 00:47:39 +02:00
|
|
|
|
<v-toolbar-title>Preplots</v-toolbar-title>
|
2020-09-30 20:04:35 +02:00
|
|
|
|
<v-spacer></v-spacer>
|
|
|
|
|
|
<v-text-field
|
|
|
|
|
|
v-model="filter"
|
|
|
|
|
|
append-icon="mdi-magnify"
|
|
|
|
|
|
label="Filter"
|
|
|
|
|
|
single-line
|
|
|
|
|
|
clearable
|
|
|
|
|
|
></v-text-field>
|
|
|
|
|
|
</v-toolbar>
|
|
|
|
|
|
</v-card-title>
|
|
|
|
|
|
<v-card-text>
|
2020-10-02 20:40:13 +02:00
|
|
|
|
|
|
|
|
|
|
<v-menu
|
|
|
|
|
|
v-model="contextMenuShow"
|
|
|
|
|
|
:position-x="contextMenuX"
|
|
|
|
|
|
:position-y="contextMenuY"
|
|
|
|
|
|
absolute
|
|
|
|
|
|
offset-y
|
|
|
|
|
|
>
|
|
|
|
|
|
<v-list dense v-if="contextMenuItem">
|
|
|
|
|
|
<v-list-item @click="setNTBA">
|
|
|
|
|
|
<v-list-item-title v-if="contextMenuItem.ntba">Unset NTBA</v-list-item-title>
|
|
|
|
|
|
<v-list-item-title v-else>Set NTBA</v-list-item-title>
|
|
|
|
|
|
</v-list-item>
|
2020-10-08 16:39:04 +02:00
|
|
|
|
<v-list-item @click="addToPlan" v-if="!contextMenuItem.ntba">
|
|
|
|
|
|
<v-list-item-title>Add to plan</v-list-item-title>
|
|
|
|
|
|
</v-list-item>
|
2020-10-02 20:40:13 +02:00
|
|
|
|
</v-list>
|
|
|
|
|
|
</v-menu>
|
2020-09-30 20:04:35 +02:00
|
|
|
|
|
|
|
|
|
|
<v-data-table
|
|
|
|
|
|
:headers="headers"
|
|
|
|
|
|
:items="items"
|
|
|
|
|
|
:search="filter"
|
|
|
|
|
|
:loading="loading"
|
|
|
|
|
|
:fixed-header="true"
|
2020-10-01 18:28:59 +02:00
|
|
|
|
:item-class="(item) => (activeItem == item && !edit) ? 'blue accent-1 elevation-3' : ''"
|
2020-09-30 20:12:15 +02:00
|
|
|
|
@click:row="setActiveItem"
|
2020-10-02 20:40:13 +02:00
|
|
|
|
@contextmenu:row="contextMenu"
|
2020-09-30 19:44:15 +02:00
|
|
|
|
>
|
2020-09-30 20:04:35 +02:00
|
|
|
|
|
|
|
|
|
|
<template v-slot:item.status="{item}">
|
|
|
|
|
|
<dougal-line-status
|
|
|
|
|
|
:preplot="item"
|
|
|
|
|
|
:sequences="sequences.filter(s => s.line == item.line)"
|
|
|
|
|
|
:sequence-href="(s) => `/projects/${$route.params.project}/log/sequence/${s.sequence}`"
|
|
|
|
|
|
>
|
2020-10-01 15:31:24 +02:00
|
|
|
|
<template v-slot:empty>
|
2020-10-02 20:40:13 +02:00
|
|
|
|
<div v-if="!item.ntba" class="sequence" title="Virgin"></div>
|
|
|
|
|
|
<div v-else class="sequence ntba" title="Not to be acquired"><span>NTBA</span></div>
|
2020-10-01 15:31:24 +02:00
|
|
|
|
</template>
|
2020-09-30 20:04:35 +02:00
|
|
|
|
</dougal-line-status>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template v-slot:item.length="props">
|
|
|
|
|
|
<span>{{ Math.round(props.value) }} m</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template v-slot:item.azimuth="props">
|
|
|
|
|
|
<span>{{ props.value.toFixed(1) }} °</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2020-10-01 18:28:59 +02:00
|
|
|
|
<template v-slot:item.remarks="{item}">
|
|
|
|
|
|
<v-text-field v-if="edit && edit.line == item.line && edit.key == 'remarks'"
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
v-model="edit.value"
|
|
|
|
|
|
prepend-icon="mdi-restore"
|
|
|
|
|
|
append-outer-icon="mdi-content-save-edit-outline"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
@click:prepend="edit.value = item.remarks; edit = null"
|
|
|
|
|
|
@click:append-outer="edit = null"
|
|
|
|
|
|
>
|
|
|
|
|
|
</v-text-field>
|
|
|
|
|
|
<div v-else>
|
|
|
|
|
|
{{item.remarks}}
|
|
|
|
|
|
<v-btn v-if="edit === null"
|
|
|
|
|
|
icon
|
|
|
|
|
|
small
|
|
|
|
|
|
title="Edit"
|
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
|
@click="editItem(item, 'remarks')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<v-icon small>mdi-square-edit-outline</v-icon>
|
|
|
|
|
|
</v-btn>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2020-09-30 20:04:35 +02:00
|
|
|
|
</v-data-table>
|
|
|
|
|
|
|
|
|
|
|
|
</v-card-text>
|
|
|
|
|
|
</v-card>
|
2020-08-08 23:59:13 +02:00
|
|
|
|
</v-container>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2020-10-02 20:40:13 +02:00
|
|
|
|
<style lang="stylus" scoped>
|
|
|
|
|
|
.ntba
|
|
|
|
|
|
background-image repeating-linear-gradient(-45deg, #ff00004d, #ff000080 10px, #d3d3d31a 10px, #d3d3d314 20px)
|
|
|
|
|
|
cursor not-allowed
|
|
|
|
|
|
display flex
|
|
|
|
|
|
align-items center
|
|
|
|
|
|
justify-content center
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
2020-08-08 23:59:13 +02:00
|
|
|
|
<script>
|
2020-08-26 17:48:55 +02:00
|
|
|
|
import { mapActions, mapGetters } from 'vuex';
|
2020-09-30 19:44:15 +02:00
|
|
|
|
import DougalLineStatus from '@/components/line-status';
|
|
|
|
|
|
|
2020-08-08 23:59:13 +02:00
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: "LineList",
|
2020-09-30 19:44:15 +02:00
|
|
|
|
|
|
|
|
|
|
components: {
|
|
|
|
|
|
DougalLineStatus
|
|
|
|
|
|
},
|
2020-08-08 23:59:13 +02:00
|
|
|
|
|
|
|
|
|
|
data () {
|
|
|
|
|
|
return {
|
|
|
|
|
|
headers: [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "line",
|
|
|
|
|
|
text: "Line"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "status",
|
|
|
|
|
|
text: "Status"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "fsp",
|
|
|
|
|
|
text: "FSP",
|
|
|
|
|
|
align: "end"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "lsp",
|
|
|
|
|
|
text: "LSP",
|
|
|
|
|
|
align: "end"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "num_points",
|
|
|
|
|
|
text: "Num. points",
|
|
|
|
|
|
align: "end"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "length",
|
|
|
|
|
|
text: "Length",
|
|
|
|
|
|
align: "end"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "azimuth",
|
|
|
|
|
|
text: "Azimuth",
|
|
|
|
|
|
align: "end"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: "remarks",
|
|
|
|
|
|
text: "Remarks"
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
items: [],
|
2020-10-01 18:28:59 +02:00
|
|
|
|
filter: null,
|
2020-09-30 19:44:15 +02:00
|
|
|
|
num_lines: null,
|
|
|
|
|
|
sequences: [],
|
2020-09-30 20:12:15 +02:00
|
|
|
|
activeItem: null,
|
2020-10-02 00:41:16 +02:00
|
|
|
|
edit: null, // {line, key, value}
|
2020-10-02 20:40:13 +02:00
|
|
|
|
queuedReload: false,
|
|
|
|
|
|
|
|
|
|
|
|
// Context menu stuff
|
|
|
|
|
|
contextMenuShow: false,
|
|
|
|
|
|
contextMenuX: 0,
|
|
|
|
|
|
contextMenuY: 0,
|
|
|
|
|
|
contextMenuItem: null
|
2020-08-08 23:59:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2020-08-26 17:48:55 +02:00
|
|
|
|
computed: {
|
2020-10-02 00:41:16 +02:00
|
|
|
|
...mapGetters(['loading', 'serverEvent'])
|
2020-08-26 17:48:55 +02:00
|
|
|
|
},
|
2020-10-01 18:28:59 +02:00
|
|
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
|
|
|
|
|
|
|
|
async edit (newVal, oldVal) {
|
|
|
|
|
|
if (newVal === null && oldVal !== null) {
|
|
|
|
|
|
const item = this.items.find(i => i.line == oldVal.line);
|
|
|
|
|
|
|
|
|
|
|
|
// Get around this Vuetify ‘feature’
|
|
|
|
|
|
// https://github.com/vuetifyjs/vuetify/issues/4144
|
|
|
|
|
|
if (oldVal.value === null) oldVal.value = "";
|
|
|
|
|
|
|
|
|
|
|
|
if (item && item[oldVal.key] != oldVal.value) {
|
|
|
|
|
|
if (await this.saveItem(oldVal)) {
|
|
|
|
|
|
item[oldVal.key] = oldVal.value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.edit = oldVal;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-10-02 00:41:16 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
async serverEvent (event) {
|
|
|
|
|
|
if (event.channel == "preplot_lines" && event.payload.pid == this.$route.params.project) {
|
|
|
|
|
|
if (!this.loading && !this.queuedReload) {
|
|
|
|
|
|
// Do not force a non-cached response if refreshing as a result
|
|
|
|
|
|
// of an event notification. We will assume that the server has
|
|
|
|
|
|
// already had time to update the cache by the time our request
|
|
|
|
|
|
// gets back to it.
|
|
|
|
|
|
this.getLines();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.queuedReload = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-10-02 01:33:58 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
queuedReload (newVal, oldVal) {
|
|
|
|
|
|
if (newVal && !oldVal && !this.loading) {
|
|
|
|
|
|
this.getLines();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
loading (newVal, oldVal) {
|
|
|
|
|
|
if (!newVal && oldVal && this.queuedReload) {
|
|
|
|
|
|
this.getLines();
|
|
|
|
|
|
}
|
2020-10-01 18:28:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
},
|
2020-08-26 17:48:55 +02:00
|
|
|
|
|
2020-08-08 23:59:13 +02:00
|
|
|
|
methods: {
|
2020-10-01 18:28:59 +02:00
|
|
|
|
|
2020-10-02 20:40:13 +02:00
|
|
|
|
contextMenu (e, {item}) {
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
this.contextMenuShow = false;
|
|
|
|
|
|
this.contextMenuX = e.clientX;
|
|
|
|
|
|
this.contextMenuY = e.clientY;
|
|
|
|
|
|
this.contextMenuItem = item;
|
|
|
|
|
|
this.$nextTick( () => this.contextMenuShow = true );
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
setNTBA () {
|
|
|
|
|
|
this.saveItem({
|
|
|
|
|
|
line: this.contextMenuItem.line,
|
|
|
|
|
|
key: 'ntba',
|
|
|
|
|
|
value: !this.contextMenuItem.ntba
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
2020-10-08 16:39:04 +02:00
|
|
|
|
|
|
|
|
|
|
async addToPlan () {
|
|
|
|
|
|
const payload = {
|
|
|
|
|
|
sequence: null,
|
|
|
|
|
|
line: this.contextMenuItem.line,
|
|
|
|
|
|
fsp: this.contextMenuItem.fsp,
|
|
|
|
|
|
lsp: this.contextMenuItem.lsp
|
|
|
|
|
|
}
|
|
|
|
|
|
console.log("Plan", payload);
|
|
|
|
|
|
const url = `/project/${this.$route.params.project}/plan`;
|
|
|
|
|
|
const init = {
|
|
|
|
|
|
method: "POST",
|
|
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
|
|
body: payload
|
|
|
|
|
|
}
|
|
|
|
|
|
await this.api([url, init]);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2020-10-01 18:28:59 +02:00
|
|
|
|
editItem (item, key) {
|
|
|
|
|
|
this.edit = {
|
|
|
|
|
|
line: item.line,
|
|
|
|
|
|
key,
|
|
|
|
|
|
value: item[key]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
async saveItem (edit) {
|
|
|
|
|
|
if (!edit) return;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const url = `/project/${this.$route.params.project}/line/${edit.line}`;
|
|
|
|
|
|
const init = {
|
|
|
|
|
|
method: "PATCH",
|
|
|
|
|
|
body: {
|
|
|
|
|
|
[edit.key]: edit.value
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let res;
|
|
|
|
|
|
await this.api([url, init, (e, r) => res = r]);
|
|
|
|
|
|
return res && res.ok;
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2020-08-08 23:59:13 +02:00
|
|
|
|
|
|
|
|
|
|
async getNumLines () {
|
|
|
|
|
|
const projectInfo = await this.api([`/project/${this.$route.params.project}`]);
|
|
|
|
|
|
this.num_lines = projectInfo.lines;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
async getLines () {
|
|
|
|
|
|
|
2020-09-30 20:04:35 +02:00
|
|
|
|
const url = `/project/${this.$route.params.project}/line`;
|
2020-08-08 23:59:13 +02:00
|
|
|
|
|
2020-10-02 00:41:16 +02:00
|
|
|
|
this.queuedReload = false;
|
2020-08-08 23:59:13 +02:00
|
|
|
|
this.items = await this.api([url]) || [];
|
|
|
|
|
|
|
|
|
|
|
|
},
|
2020-09-30 19:44:15 +02:00
|
|
|
|
|
|
|
|
|
|
async getSequences () {
|
|
|
|
|
|
const url = `/project/${this.$route.params.project}/sequence`;
|
|
|
|
|
|
this.sequences = await this.api([url]) || [];
|
|
|
|
|
|
},
|
2020-08-08 23:59:13 +02:00
|
|
|
|
|
2020-09-30 20:12:15 +02:00
|
|
|
|
setActiveItem (item) {
|
|
|
|
|
|
this.activeItem = this.activeItem == item
|
|
|
|
|
|
? null
|
|
|
|
|
|
: item;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2020-08-08 23:59:13 +02:00
|
|
|
|
...mapActions(["api"])
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
mounted () {
|
|
|
|
|
|
this.getLines();
|
|
|
|
|
|
this.getNumLines();
|
2020-09-30 19:44:15 +02:00
|
|
|
|
this.getSequences();
|
2020-08-08 23:59:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|