mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 13:17:08 +00:00
Merge branch '108-remove-edit-controls-for-read-only-users' into 'devel'
Resolve "Remove edit controls for read-only users" Closes #108 See merge request wgp/dougal/software!8
This commit is contained in:
@@ -3,4 +3,12 @@ function user (state) {
|
||||
return state.user;
|
||||
}
|
||||
|
||||
export default { user };
|
||||
function writeaccess (state) {
|
||||
return state.user && ["user", "admin"].includes(state.user.role);
|
||||
}
|
||||
|
||||
function adminaccess (state) {
|
||||
return state.user && state.user.role == "admin";
|
||||
}
|
||||
|
||||
export default { user, writeaccess, adminaccess };
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
|
||||
<v-menu
|
||||
<v-menu v-if="writeaccess"
|
||||
v-model="contextMenuShow"
|
||||
:position-x="contextMenuX"
|
||||
:position-y="contextMenuY"
|
||||
@@ -139,8 +139,9 @@
|
||||
@click:append-outer="edit = null"
|
||||
>
|
||||
</v-text-field>
|
||||
<div v-else v-html="$options.filters.markdownInline(item.remarks)">
|
||||
<v-btn v-if="edit === null"
|
||||
<div v-else>
|
||||
<span v-html="$options.filters.markdownInline(item.remarks)"></span>
|
||||
<v-btn v-if="writeaccess && edit === null"
|
||||
icon
|
||||
small
|
||||
title="Edit"
|
||||
@@ -246,7 +247,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['user', 'loading', 'serverEvent'])
|
||||
...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</span>
|
||||
</v-toolbar-title>
|
||||
|
||||
<dougal-event-edit-dialog
|
||||
<dougal-event-edit-dialog v-if="writeaccess"
|
||||
v-model="eventDialog"
|
||||
:allowed-labels="userLabels"
|
||||
:preset-remarks="presetRemarks"
|
||||
@@ -108,141 +108,146 @@
|
||||
</template>
|
||||
|
||||
<template v-slot:item.remarks="{item}">
|
||||
<v-edit-dialog v-if="item.items"
|
||||
large
|
||||
@save="rowEditorSave"
|
||||
@cancel="rowEditorCancel"
|
||||
@open="rowEditorOpen(item)"
|
||||
@close="rowEditorClose"
|
||||
> <div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div>
|
||||
<template v-slot:input>
|
||||
<h3>{{
|
||||
editedRow.sequence
|
||||
? `${editedRow.sequence} @ ${editedRow.point}`
|
||||
: editedRow.tstamp
|
||||
? editedRow.tstamp.replace(/(.{10})T(.{8}).{4}Z$/, "$1 $2")
|
||||
: editedRow.key
|
||||
}}</h3><hr/>
|
||||
<template v-if="writeaccess">
|
||||
<v-edit-dialog v-if="item.items"
|
||||
large
|
||||
@save="rowEditorSave"
|
||||
@cancel="rowEditorCancel"
|
||||
@open="rowEditorOpen(item)"
|
||||
@close="rowEditorClose"
|
||||
> <div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div>
|
||||
<template v-slot:input>
|
||||
<h3>{{
|
||||
editedRow.sequence
|
||||
? `${editedRow.sequence} @ ${editedRow.point}`
|
||||
: editedRow.tstamp
|
||||
? editedRow.tstamp.replace(/(.{10})T(.{8}).{4}Z$/, "$1 $2")
|
||||
: editedRow.key
|
||||
}}</h3><hr/>
|
||||
|
||||
|
||||
<dougal-context-menu
|
||||
:value="remarksMenu"
|
||||
@input="addPresetRemark"
|
||||
:items="presetRemarks"
|
||||
absolute
|
||||
></dougal-context-menu>
|
||||
<dougal-context-menu
|
||||
:value="remarksMenu"
|
||||
@input="addPresetRemark"
|
||||
:items="presetRemarks"
|
||||
absolute
|
||||
></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-model="editedItem.remarks"
|
||||
v-model="props.item.remarks[0]"
|
||||
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>
|
||||
|
||||
></v-text-field>
|
||||
</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-model="props.item.remarks[0]"
|
||||
label="Edit"
|
||||
single-line
|
||||
></v-text-field>
|
||||
</template>
|
||||
</v-edit-dialog>
|
||||
</v-edit-dialog>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-html="$options.filters.markdownInline(item.items.map(i => i.remarks).join('<br/>'))"></div>
|
||||
</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})
|
||||
|
||||
},
|
||||
@@ -527,14 +532,19 @@ export default {
|
||||
},
|
||||
|
||||
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`;
|
||||
await this.api([url, {
|
||||
method: "POST",
|
||||
body: event
|
||||
}]);
|
||||
this.showSnack(["New event saved", "success"]);
|
||||
this.queuedReload = true;
|
||||
this.getEvents({cache: "reload"});
|
||||
}, callback]);
|
||||
},
|
||||
|
||||
rowEditorOpen (row) {
|
||||
|
||||
@@ -83,13 +83,13 @@
|
||||
small
|
||||
:color="labels[label] && labels[label].view.colour"
|
||||
:title="labels[label] && labels[label].view.description"
|
||||
:close="label == 'QCAccepted'"
|
||||
:close="writeaccess && label == 'QCAccepted'"
|
||||
@click:close="unaccept(item)">
|
||||
{{label}}
|
||||
</v-chip>
|
||||
|
||||
<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">
|
||||
<v-btn
|
||||
:class="{'text--disabled': !hover}"
|
||||
@@ -226,7 +226,7 @@ export default {
|
||||
return values;
|
||||
},
|
||||
|
||||
...mapGetters(['loading'])
|
||||
...mapGetters(['writeaccess', 'loading'])
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
offset-y
|
||||
>
|
||||
<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>
|
||||
<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>
|
||||
<v-list-group>
|
||||
@@ -102,26 +102,39 @@
|
||||
<v-card outlined class="flex-grow-1">
|
||||
<v-card-title>
|
||||
Acquisition remarks
|
||||
<v-btn v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks'"
|
||||
class="ml-3"
|
||||
icon
|
||||
small
|
||||
title="Save edits"
|
||||
:disabled="loading"
|
||||
@click="edit = null"
|
||||
>
|
||||
<v-icon small>mdi-content-save-edit-outline</v-icon>
|
||||
</v-btn>
|
||||
<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-if="writeaccess">
|
||||
<template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks'">
|
||||
<v-btn
|
||||
class="ml-3"
|
||||
icon
|
||||
small
|
||||
title="Cancel edit"
|
||||
:disabled="loading"
|
||||
@click="edit.value = item.remarks; edit = null"
|
||||
>
|
||||
<v-icon small>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-if="edit.value != item.remarks"
|
||||
icon
|
||||
small
|
||||
title="Save edits"
|
||||
:disabled="loading"
|
||||
@click="edit = null"
|
||||
>
|
||||
<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-subtitle>
|
||||
</v-card-subtitle>
|
||||
@@ -141,26 +154,39 @@
|
||||
<v-card outlined class="flex-grow-1" v-if="item.remarks_final !== null">
|
||||
<v-card-title>
|
||||
Processing remarks
|
||||
<v-btn v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks_final'"
|
||||
class="ml-3"
|
||||
icon
|
||||
small
|
||||
title="Save edits"
|
||||
:disabled="loading"
|
||||
@click="edit = null"
|
||||
>
|
||||
<v-icon small>mdi-content-save-edit-outline</v-icon>
|
||||
</v-btn>
|
||||
<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-if="writeaccess">
|
||||
<template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks_final'">
|
||||
<v-btn
|
||||
class="ml-3"
|
||||
icon
|
||||
small
|
||||
title="Cancel edit"
|
||||
:disabled="loading"
|
||||
@click="edit.value = item.remarks_final; edit = null"
|
||||
>
|
||||
<v-icon small>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-if="edit.value != item.remarks_final"
|
||||
icon
|
||||
small
|
||||
title="Save edits"
|
||||
:disabled="loading"
|
||||
@click="edit = null"
|
||||
>
|
||||
<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-subtitle>
|
||||
</v-card-subtitle>
|
||||
@@ -455,7 +481,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['user', 'loading', 'serverEvent'])
|
||||
...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
||||
Reference in New Issue
Block a user