Refactor client-side access checks.

Go from a Vuex based to a mixin based approach.
This commit is contained in:
D. Berge
2025-07-12 11:22:33 +02:00
parent d21cde20fc
commit c8b2047483
11 changed files with 78 additions and 47 deletions

View File

@@ -5,7 +5,7 @@
max-width="600"
>
<template v-slot:activator="{ on, attrs }">
<v-btn v-if="adminaccess"
<v-btn v-if="adminaccess()"
title="Create a new project from scratch. Generally, it's preferable to clone an existing project (right-click → Clone)"
small
outlined
@@ -31,6 +31,7 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import DougalProjectSettingsNameIdGeodetics from '@/components/project-settings/name-id-geodetics'
import AccessMixin from '@/mixins/access';
export default {
name: 'DougalAppBarExtensionProjectList',
@@ -39,6 +40,10 @@ export default {
DougalProjectSettingsNameIdGeodetics
},
mixins: [
AccessMixin
],
data() {
return {
dialogOpen: false,
@@ -50,10 +55,6 @@ export default {
};
},
computed: {
...mapGetters(["adminaccess"])
},
methods: {
async save (data) {
this.dialogOpen = false;

View File

@@ -1,7 +1,7 @@
<template>
<v-tabs :value="tab" show-arrows v-if="page != 'configuration'">
<v-tab v-for="tab, index in tabs" :key="index" link :to="tabLink(tab.href)" v-text="tab.text"></v-tab>
<template v-if="adminaccess">
<template v-if="adminaccess()">
<v-spacer></v-spacer>
<v-tab :to="tabLink('configuration')" class="orange--text darken-3" title="Edit project settings"><v-icon small left color="orange darken-3">mdi-cog-outline</v-icon> Settings</v-tab>
</template>
@@ -15,9 +15,15 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import AccessMixin from '@/mixins/access';
export default {
name: 'DougalAppBarExtensionProject',
mixins: [
AccessMixin
],
data() {
return {
tabs: [
@@ -44,7 +50,6 @@ export default {
return this.tabs.findIndex(t => t.href == this.page);
},
...mapGetters(["adminaccess"])
},
methods: {

View File

@@ -127,7 +127,7 @@ export default {
},
computed: {
...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
...mapGetters(['user', 'loading', 'serverEvent'])
},
methods: {

View File

@@ -240,7 +240,7 @@ export default {
return this.sequences[0]?.sequence;
},
...mapGetters(['user', 'preferences', 'writeaccess', 'loading', 'serverEvent'])
...mapGetters(['user', 'preferences', 'loading', 'serverEvent'])
},
methods: {

View File

@@ -17,7 +17,7 @@
</v-card-title>
<v-card-text>
<v-menu v-if="writeaccess"
<v-menu v-if="writeaccess()"
v-model="contextMenuShow"
:position-x="contextMenuX"
:position-y="contextMenuY"
@@ -164,7 +164,7 @@
</v-text-field>
<div v-else>
<span v-html="$options.filters.markdownInline(item.remarks)"></span>
<v-btn v-if="writeaccess && edit === null"
<v-btn v-if="writeaccess() && edit === null"
icon
small
title="Edit"
@@ -196,6 +196,7 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import DougalLineStatus from '@/components/line-status';
import AccessMixin from '@/mixins/access';
export default {
name: "LineList",
@@ -204,6 +205,10 @@ export default {
DougalLineStatus
},
mixins: [
AccessMixin
],
data () {
return {
headers: [
@@ -281,7 +286,7 @@ export default {
},
computed: {
...mapGetters(['user', 'writeaccess', 'linesLoading', 'lines', 'sequences', 'plannedSequences'])
...mapGetters(['user', 'linesLoading', 'lines', 'sequences', 'plannedSequences'])
},
watch: {

View File

@@ -44,7 +44,7 @@
>mdi-format-list-numbered</v-icon>
</a>
<dougal-event-edit v-if="writeaccess"
<dougal-event-edit v-if="writeaccess()"
v-model="eventDialog"
v-bind="editedEvent"
:available-labels="userLabels"
@@ -54,7 +54,7 @@
>
</dougal-event-edit>
<dougal-event-edit-labels v-if="writeaccess"
<dougal-event-edit-labels v-if="writeaccess()"
v-model="eventLabelsDialog"
:labels="userLabels"
:selected="contextMenuItem ? contextMenuItem.labels||[] : []"
@@ -171,7 +171,7 @@
<v-card-text>
<!-- BEGIN Context menu for log entries -->
<v-menu v-if="writeaccess"
<v-menu v-if="writeaccess()"
v-model="contextMenuShow"
:position-x="contextMenuX"
:position-y="contextMenuY"
@@ -325,7 +325,7 @@
@click="labelSearch=label"
>{{label}}</v-chip>
</span>
<dougal-event-edit-history v-if="entry.has_edits && writeaccess"
<dougal-event-edit-history v-if="entry.has_edits && writeaccess()"
:id="entry.id"
:disabled="eventsLoading"
:labels="labels"
@@ -541,7 +541,7 @@ export default {
}
},
...mapGetters(['user', 'writeaccess', 'eventsLoading', 'online', 'sequence', 'line', 'point', 'position', 'timestamp', 'lineName', 'events', 'labels', 'userLabels', 'projectConfiguration']),
...mapGetters(['user', 'eventsLoading', 'online', 'sequence', 'line', 'point', 'position', 'timestamp', 'lineName', 'events', 'labels', 'userLabels', 'projectConfiguration']),
...mapState({projectSchema: state => state.project.projectSchema})
},

View File

@@ -50,7 +50,7 @@
</v-card-title>
<v-card-text>
<v-menu v-if="writeaccess"
<v-menu v-if="writeaccess()"
v-model="contextMenuShow"
:position-x="contextMenuX"
:position-y="contextMenuY"
@@ -68,7 +68,7 @@
<v-card class="mb-5" flat>
<v-card-title class="text-overline">
Comments
<template v-if="writeaccess">
<template v-if="writeaccess()">
<v-btn v-if="!editRemarks"
class="ml-3"
small
@@ -131,7 +131,7 @@
</template>
<template v-slot:item.sequence="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'sequence')"
@save="edit = null"
@@ -156,7 +156,7 @@
</template>
<template v-slot:item.name="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'name')"
@save="edit = null"
@@ -175,7 +175,7 @@
</template>
<template v-slot:item.fsp="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'fsp')"
@save="edit = null"
@@ -195,7 +195,7 @@
</template>
<template v-slot:item.lsp="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'lsp')"
@save="edit = null"
@@ -215,7 +215,7 @@
</template>
<template v-slot:item.ts0="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'ts0', item.ts0.toISOString())"
@save="edit = null"
@@ -235,7 +235,7 @@
</template>
<template v-slot:item.ts1="{item, value}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'ts1', item.ts1.toISOString())"
@save="edit = null"
@@ -263,7 +263,7 @@
</template>
<template v-slot:item.remarks="{item}">
<v-text-field v-if="writeaccess && edit && edit.sequence == item.sequence && edit.key == 'remarks'"
<v-text-field v-if="writeaccess() && edit && edit.sequence == item.sequence && edit.key == 'remarks'"
type="text"
v-model="edit.value"
prepend-icon="mdi-restore"
@@ -275,7 +275,7 @@
</v-text-field>
<div v-else>
<span v-html="$options.filters.markdownInline(item.remarks)"></span>
<v-btn v-if="edit === null && writeaccess"
<v-btn v-if="edit === null && writeaccess()"
icon
small
title="Edit"
@@ -289,7 +289,7 @@
</template>
<template v-slot:item.speed="{item}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'speed', knots(item).toFixed(1))"
@save="edit = null"
@@ -311,7 +311,7 @@
</template>
<template v-slot:item.lag="{item}">
<v-edit-dialog v-if="writeaccess"
<v-edit-dialog v-if="writeaccess()"
large
@open="editItem(item, 'lagAfter', Math.round(lagAfter(item)/(60*1000)))"
@save="edit = null"
@@ -344,6 +344,7 @@
<script>
import suncalc from 'suncalc';
import { mapActions, mapGetters } from 'vuex';
import AccessMixin from '@/mixins/access';
export default {
name: "Plan",
@@ -351,6 +352,10 @@ export default {
components: {
},
mixins: [
AccessMixin
],
data () {
return {
headers: [
@@ -557,7 +562,7 @@ export default {
},
computed: {
...mapGetters(['user', 'writeaccess', 'plannedSequencesLoading', 'plannedSequences', 'planRemarks'])
...mapGetters(['user', 'plannedSequencesLoading', 'plannedSequences', 'planRemarks'])
},
watch: {

View File

@@ -62,7 +62,7 @@
</v-data-table>
<v-menu v-if="adminaccess"
<v-menu v-if="adminaccess(contextMenuItem)"
v-model="contextMenuShow"
:position-x="contextMenuX"
:position-y="contextMenuY"
@@ -106,6 +106,7 @@ td p:last-of-type {
<script>
import { mapActions, mapGetters } from 'vuex';
import DougalProjectSettingsNameIdRootpath from '@/components/project-settings/name-id-rootpath'
import AccessMixin from '@/mixins/access';
export default {
name: "ProjectList",
@@ -114,6 +115,10 @@ export default {
DougalProjectSettingsNameIdRootpath
},
mixins: [
AccessMixin
],
data () {
return {
headers: [
@@ -179,7 +184,7 @@ export default {
: this.items.filter(i => !i.archived);
},
...mapGetters(['loading', 'serverEvent', 'adminaccess', 'projects'])
...mapGetters(['loading', 'serverEvent', 'projects'])
},
watch: {

View File

@@ -571,7 +571,7 @@ export default {
return messages;
},
...mapGetters(['user', 'writeaccess', 'loading', 'serverEvent'])
...mapGetters(['user', 'loading', 'serverEvent'])
},
methods: {

View File

@@ -82,13 +82,13 @@
small
:color="labels[label] && labels[label].view.colour"
:title="labels[label] && labels[label].view.description"
:close="writeaccess && label == 'QCAccepted'"
:close="writeaccess() && label == 'QCAccepted'"
@click:close="unaccept(item)"
>
{{label}}
</v-chip>
<dougal-qc-acceptance v-if="writeaccess"
<dougal-qc-acceptance v-if="writeaccess()"
:item="item"
@accept="accept"
@unaccept="unaccept"
@@ -105,7 +105,7 @@
>
</v-chip>
<dougal-qc-acceptance v-if="writeaccess"
<dougal-qc-acceptance v-if="writeaccess()"
:item="item"
@accept="accept"
@unaccept="unaccept"
@@ -113,7 +113,7 @@
</div>
<div class="text--secondary" v-else>
<dougal-qc-acceptance v-if="writeaccess"
<dougal-qc-acceptance v-if="writeaccess()"
:item="item"
@accept="accept"
@unaccept="unaccept"
@@ -140,6 +140,7 @@
import { mapActions, mapGetters } from 'vuex';
import { withParentProps } from '@/lib/utils';
import DougalQcAcceptance from '@/components/qc-acceptance';
import AccessMixin from '@/mixins/access';
export default {
name: "QC",
@@ -148,6 +149,10 @@ export default {
DougalQcAcceptance
},
mixins: [
AccessMixin
],
data () {
return {
updatedOn: null,
@@ -227,7 +232,7 @@ export default {
return values;
},
...mapGetters(['writeaccess', 'loading'])
...mapGetters(['loading'])
},
watch: {

View File

@@ -28,10 +28,10 @@
offset-y
>
<v-list dense v-if="contextMenuItem">
<v-list-item @click="addToPlan(false); contextMenuShow=false" v-if="writeaccess">
<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-if="writeaccess">
<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-item
@@ -85,7 +85,7 @@
<!-- Item is not in queue -->
<v-list-item
v-if="writeaccess && !contextMenuItemInTransferQueue"
v-if="writeaccess() && !contextMenuItemInTransferQueue"
@click="addToTransferQueue(); contextMenuShow=false"
>
<v-list-item-content>
@@ -97,7 +97,7 @@
</v-list-item>
<!-- Item queued, not yet sent -->
<v-list-item two-line
v-else-if="writeaccess && contextMenuItemInTransferQueue.status == 'queued'"
v-else-if="writeaccess() && contextMenuItemInTransferQueue.status == 'queued'"
@click="removeFromTransferQueue(); contextMenuShow=false"
>
<v-list-item-content>
@@ -112,7 +112,7 @@
</v-list-item>
<!-- Item already sent -->
<v-list-item two-line
v-else-if="writeaccess && contextMenuItemInTransferQueue.status == 'sent'"
v-else-if="writeaccess() && contextMenuItemInTransferQueue.status == 'sent'"
@click="addToTransferQueue(); contextMenuShow=false"
>
<v-list-item-content>
@@ -127,7 +127,7 @@
</v-list-item>
<!-- Item sending was cancelled -->
<v-list-item two-line
v-else-if="writeaccess && contextMenuItemInTransferQueue.status == 'cancelled'"
v-else-if="writeaccess() && contextMenuItemInTransferQueue.status == 'cancelled'"
@click="addToTransferQueue(); contextMenuShow=false"
>
<v-list-item-content>
@@ -170,7 +170,7 @@
<v-card outlined class="flex-grow-1">
<v-card-title>
Acquisition remarks
<template v-if="writeaccess">
<template v-if="writeaccess()">
<template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks'">
<v-btn
class="ml-3"
@@ -222,7 +222,7 @@
<v-card outlined class="flex-grow-1" v-if="item.remarks_final !== null">
<v-card-title>
Processing remarks
<template v-if="writeaccess">
<template v-if="writeaccess()">
<template v-if="edit && edit.sequence == item.sequence && edit.key == 'remarks_final'">
<v-btn
class="ml-3"
@@ -492,10 +492,15 @@ tr :nth-child(5), tr :nth-child(8), tr :nth-child(11), tr :nth-child(14) {
import { mapActions, mapGetters } from 'vuex';
import { basename } from 'path';
import throttle from '@/lib/throttle';
import AccessMixin from '@/mixins/access';
export default {
name: "SequenceList",
mixins: [
AccessMixin
],
data () {
return {
headers: [
@@ -616,7 +621,7 @@ export default {
return this.queuedItems.find(i => i.payload.sequence == this.contextMenuItem.sequence);
},
...mapGetters(['user', 'writeaccess', 'sequencesLoading', 'sequences'])
...mapGetters(['user', 'sequencesLoading', 'sequences'])
},
watch: {