Hide edit controls from ready-only users

This commit is contained in:
D. Berge
2021-05-16 19:55:31 +02:00
parent 0d9f7ac4ec
commit 418f1a00b8
4 changed files with 220 additions and 183 deletions

View File

@@ -16,7 +16,7 @@
</v-card-title> </v-card-title>
<v-card-text> <v-card-text>
<v-menu <v-menu v-if="writeaccess"
v-model="contextMenuShow" v-model="contextMenuShow"
:position-x="contextMenuX" :position-x="contextMenuX"
:position-y="contextMenuY" :position-y="contextMenuY"
@@ -139,8 +139,9 @@
@click:append-outer="edit = null" @click:append-outer="edit = null"
> >
</v-text-field> </v-text-field>
<div v-else v-html="$options.filters.markdownInline(item.remarks)"> <div v-else>
<v-btn v-if="edit === null" <span v-html="$options.filters.markdownInline(item.remarks)"></span>
<v-btn v-if="writeaccess && edit === null"
icon icon
small small
title="Edit" title="Edit"
@@ -246,7 +247,7 @@ export default {
}, },
computed: { computed: {
...mapGetters(['user', 'loading', 'serverEvent']) ...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
}, },
watch: { watch: {

View File

@@ -33,7 +33,7 @@
</span> </span>
</v-toolbar-title> </v-toolbar-title>
<dougal-event-edit-dialog <dougal-event-edit-dialog v-if="writeaccess"
v-model="eventDialog" v-model="eventDialog"
:allowed-labels="userLabels" :allowed-labels="userLabels"
:preset-remarks="presetRemarks" :preset-remarks="presetRemarks"
@@ -108,141 +108,146 @@
</template> </template>
<template v-slot:item.remarks="{item}"> <template v-slot:item.remarks="{item}">
<v-edit-dialog v-if="item.items" <template v-if="writeaccess">
large <v-edit-dialog v-if="item.items"
@save="rowEditorSave" large
@cancel="rowEditorCancel" @save="rowEditorSave"
@open="rowEditorOpen(item)" @cancel="rowEditorCancel"
@close="rowEditorClose" @open="rowEditorOpen(item)"
> <div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div> @close="rowEditorClose"
<template v-slot:input> > <div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div>
<h3>{{ <template v-slot:input>
editedRow.sequence <h3>{{
? `${editedRow.sequence} @ ${editedRow.point}` editedRow.sequence
: editedRow.tstamp ? `${editedRow.sequence} @ ${editedRow.point}`
? editedRow.tstamp.replace(/(.{10})T(.{8}).{4}Z$/, "$1 $2") : editedRow.tstamp
: editedRow.key ? editedRow.tstamp.replace(/(.{10})T(.{8}).{4}Z$/, "$1 $2")
}}</h3><hr/> : editedRow.key
}}</h3><hr/>
<dougal-context-menu <dougal-context-menu
:value="remarksMenu" :value="remarksMenu"
@input="addPresetRemark" @input="addPresetRemark"
:items="presetRemarks" :items="presetRemarks"
absolute absolute
></dougal-context-menu> ></dougal-context-menu>
<template v-for="editedItem in editedRow.items"> <template v-for="editedItem in editedRow.items">
<v-text-field
v-model="editedItem.remarks"
label="Edit"
single-line
hide-details="auto"
>
<template v-slot:prepend>
<v-icon v-show="!editedItem.remarks && presetRemarks"
title="Select predefined comments"
color="primary"
@click="(e) => {remarksMenuItem = editedItem; remarksMenu = e}"
>
mdi-dots-vertical
</v-icon>
</template>
<template v-slot:append v-if="editedItem.remarks || editedItem.labels.filter(l => labels[l].model.user).length">
<v-hover v-slot:default="{hover}">
<v-icon
title="Remove comment"
:color="hover ? 'error' : 'error lighten-4'"
@click="removeEvent(editedItem, editedRow)"
>mdi-minus-circle</v-icon>
</v-hover>
</template>
</v-text-field>
<v-container>
<v-row no-gutters>
<v-col class="flex-grow-0">
<!-- Add a new label control -->
<v-edit-dialog
large
@save="addLabel(editedItem)"
@cancel="selectedLabels=[]"
>
<v-icon
small
title="Add label"
>mdi-tag-plus</v-icon>
<template v-slot:input>
<v-autocomplete
:items="availableLabels(editedItem.labels)"
v-model="selectedLabels"
label="Add label"
chips
deletable-chips
multiple
autofocus
@keydown.stop="(e) => {if (e.key == 'Enter') debug(e)}"
@input="labelSearch = null;"
:search-input.sync="labelSearch"
>
<template v-slot:selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
small
@click="data.select"
:color="labels[data.item].view.colour"
:title="labels[data.item].view.description"
>{{data.item}}</v-chip>
</template>
</v-autocomplete>
</template>
</v-edit-dialog>
</v-col>
<v-col class="flex-grow-0">
<v-chip-group>
<v-chip v-for="label in editedItem.labels" :key="label"
small
:close="labels[label].model.user"
:color="labels[label].view.colour"
:title="labels[label].view.description"
@click:close="removeLabel(label, editedItem)"
>{{label}}</v-chip>
</v-chip-group>
</v-col>
</v-row>
</v-container>
</template>
<v-icon v-if="editedRow.items.length == 0 || editedRow.items[editedRow.items.length-1].remarks"
color="primary"
title="Add comment"
class="mb-2"
@click="addEvent"
>mdi-plus-circle</v-icon>
</template>
</v-edit-dialog>
<v-edit-dialog v-else
@save="rowEditorSave"
@cancel="rowEditorCancel"
@open="rowEditorOpen"
@close="rowEditorClose"
>
<template v-slot:input>
<v-text-field <v-text-field
v-model="editedItem.remarks" v-model="props.item.remarks[0]"
label="Edit" label="Edit"
single-line single-line
hide-details="auto" ></v-text-field>
>
<template v-slot:prepend>
<v-icon v-show="!editedItem.remarks && presetRemarks"
title="Select predefined comments"
color="primary"
@click="(e) => {remarksMenuItem = editedItem; remarksMenu = e}"
>
mdi-dots-vertical
</v-icon>
</template>
<template v-slot:append v-if="editedItem.remarks || editedItem.labels.filter(l => labels[l].model.user).length">
<v-hover v-slot:default="{hover}">
<v-icon
title="Remove comment"
:color="hover ? 'error' : 'error lighten-4'"
@click="removeEvent(editedItem, editedRow)"
>mdi-minus-circle</v-icon>
</v-hover>
</template>
</v-text-field>
<v-container>
<v-row no-gutters>
<v-col class="flex-grow-0">
<!-- Add a new label control -->
<v-edit-dialog
large
@save="addLabel(editedItem)"
@cancel="selectedLabels=[]"
>
<v-icon
small
title="Add label"
>mdi-tag-plus</v-icon>
<template v-slot:input>
<v-autocomplete
:items="availableLabels(editedItem.labels)"
v-model="selectedLabels"
label="Add label"
chips
deletable-chips
multiple
autofocus
@keydown.stop="(e) => {if (e.key == 'Enter') debug(e)}"
@input="labelSearch = null;"
:search-input.sync="labelSearch"
>
<template v-slot:selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
small
@click="data.select"
:color="labels[data.item].view.colour"
:title="labels[data.item].view.description"
>{{data.item}}</v-chip>
</template>
</v-autocomplete>
</template>
</v-edit-dialog>
</v-col>
<v-col class="flex-grow-0">
<v-chip-group>
<v-chip v-for="label in editedItem.labels" :key="label"
small
:close="labels[label].model.user"
:color="labels[label].view.colour"
:title="labels[label].view.description"
@click:close="removeLabel(label, editedItem)"
>{{label}}</v-chip>
</v-chip-group>
</v-col>
</v-row>
</v-container>
</template> </template>
</v-edit-dialog>
<v-icon v-if="editedRow.items.length == 0 || editedRow.items[editedRow.items.length-1].remarks" </template>
color="primary" <template v-else>
title="Add comment" <div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div>
class="mb-2" </template>
@click="addEvent"
>mdi-plus-circle</v-icon>
</template>
</v-edit-dialog>
<v-edit-dialog v-else
@save="rowEditorSave"
@cancel="rowEditorCancel"
@open="rowEditorOpen"
@close="rowEditorClose"
>
<template v-slot:input>
<v-text-field
v-model="props.item.remarks[0]"
label="Edit"
single-line
></v-text-field>
</template>
</v-edit-dialog>
</template> </template>
@@ -400,7 +405,7 @@ export default {
} }
}, },
...mapGetters(['user', 'loading', 'online', 'sequence', 'line', 'point', 'lineName', 'serverEvent']), ...mapGetters(['user', 'writeaccess', 'loading', 'online', 'sequence', 'line', 'point', 'lineName', 'serverEvent']),
...mapState({projectSchema: state => state.project.projectSchema}) ...mapState({projectSchema: state => state.project.projectSchema})
}, },
@@ -527,14 +532,19 @@ export default {
}, },
async saveEvent (event) { async saveEvent (event) {
function callback (err, res) {
if (!err && res.ok) {
this.showSnack(["New event saved", "success"]);
this.queuedReload = true;
this.getEvents({cache: "reload"});
}
}
const url = `/project/${this.$route.params.project}/event`; const url = `/project/${this.$route.params.project}/event`;
await this.api([url, { await this.api([url, {
method: "POST", method: "POST",
body: event body: event
}]); }, callback]);
this.showSnack(["New event saved", "success"]);
this.queuedReload = true;
this.getEvents({cache: "reload"});
}, },
rowEditorOpen (row) { rowEditorOpen (row) {

View File

@@ -83,13 +83,13 @@
small small
:color="labels[label] && labels[label].view.colour" :color="labels[label] && labels[label].view.colour"
:title="labels[label] && labels[label].view.description" :title="labels[label] && labels[label].view.description"
:close="label == 'QCAccepted'" :close="writeaccess && label == 'QCAccepted'"
@click:close="unaccept(item)"> @click:close="unaccept(item)">
{{label}} {{label}}
</v-chip> </v-chip>
<template v-if="!item.labels || !item.labels.includes('QCAccepted')"> <template v-if="!item.labels || !item.labels.includes('QCAccepted')">
<v-hover v-slot:default="{hover}"> <v-hover v-slot:default="{hover}" v-if="writeaccess">
<span v-if="item.children && item.children.length"> <span v-if="item.children && item.children.length">
<v-btn <v-btn
:class="{'text--disabled': !hover}" :class="{'text--disabled': !hover}"
@@ -226,7 +226,7 @@ export default {
return values; return values;
}, },
...mapGetters(['loading']) ...mapGetters(['writeaccess', 'loading'])
}, },
watch: { watch: {

View File

@@ -28,10 +28,10 @@
offset-y offset-y
> >
<v-list dense v-if="contextMenuItem"> <v-list dense v-if="contextMenuItem">
<v-list-item @click="addToPlan(false); contextMenuShow=false"> <v-list-item @click="addToPlan(false); contextMenuShow=false" v-if="writeaccess">
<v-list-item-title>Reshoot</v-list-item-title> <v-list-item-title>Reshoot</v-list-item-title>
</v-list-item> </v-list-item>
<v-list-item @click="addToPlan(true); contextMenuShow=false"> <v-list-item @click="addToPlan(true); contextMenuShow=false" v-if="writeaccess">
<v-list-item-title>Reshoot with overlap</v-list-item-title> <v-list-item-title>Reshoot with overlap</v-list-item-title>
</v-list-item> </v-list-item>
<v-list-group> <v-list-group>
@@ -102,26 +102,39 @@
<v-card outlined class="flex-grow-1"> <v-card outlined class="flex-grow-1">
<v-card-title> <v-card-title>
Acquisition remarks Acquisition remarks
<v-btn v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks'" <template v-if="writeaccess">
class="ml-3" <template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks'">
icon <v-btn
small class="ml-3"
title="Save edits" icon
:disabled="loading" small
@click="edit = null" title="Cancel edit"
> :disabled="loading"
<v-icon small>mdi-content-save-edit-outline</v-icon> @click="edit.value = item.remarks; edit = null"
</v-btn> >
<v-btn v-else-if="edit === null" <v-icon small>mdi-close</v-icon>
class="ml-3" </v-btn>
icon <v-btn v-if="edit.value != item.remarks"
small icon
title="Edit" small
:disabled="loading" title="Save edits"
@click="editItem(item, 'remarks')" :disabled="loading"
> @click="edit = null"
<v-icon small>mdi-square-edit-outline</v-icon> >
</v-btn> <v-icon small>mdi-content-save-edit-outline</v-icon>
</v-btn>
</template>
<v-btn v-else-if="edit === null"
class="ml-3"
icon
small
title="Edit"
:disabled="loading"
@click="editItem(item, 'remarks')"
>
<v-icon small>mdi-square-edit-outline</v-icon>
</v-btn>
</template>
</v-card-title> </v-card-title>
<v-card-subtitle> <v-card-subtitle>
</v-card-subtitle> </v-card-subtitle>
@@ -141,26 +154,39 @@
<v-card outlined class="flex-grow-1" v-if="item.remarks_final !== null"> <v-card outlined class="flex-grow-1" v-if="item.remarks_final !== null">
<v-card-title> <v-card-title>
Processing remarks Processing remarks
<v-btn v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks_final'" <template v-if="writeaccess">
class="ml-3" <template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks_final'">
icon <v-btn
small class="ml-3"
title="Save edits" icon
:disabled="loading" small
@click="edit = null" title="Cancel edit"
> :disabled="loading"
<v-icon small>mdi-content-save-edit-outline</v-icon> @click="edit.value = item.remarks_final; edit = null"
</v-btn> >
<v-btn v-else-if="edit === null" <v-icon small>mdi-close</v-icon>
class="ml-3" </v-btn>
icon <v-btn v-if="edit.value != item.remarks_final"
small icon
title="Edit" small
:disabled="loading" title="Save edits"
@click="editItem(item, 'remarks_final')" :disabled="loading"
> @click="edit = null"
<v-icon small>mdi-square-edit-outline</v-icon> >
</v-btn> <v-icon small>mdi-content-save-edit-outline</v-icon>
</v-btn>
</template>
<v-btn v-else-if="edit === null"
class="ml-3"
icon
small
title="Edit"
:disabled="loading"
@click="editItem(item, 'remarks_final')"
>
<v-icon small>mdi-square-edit-outline</v-icon>
</v-btn>
</template>
</v-card-title> </v-card-title>
<v-card-subtitle> <v-card-subtitle>
</v-card-subtitle> </v-card-subtitle>
@@ -455,7 +481,7 @@ export default {
}, },
computed: { computed: {
...mapGetters(['user', 'loading', 'serverEvent']) ...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
}, },
watch: { watch: {