Only allow workflows on owned boards, and show the board in the table
Build package / php-lint (8.4) (push) Successful in 1m7s
Build package / php-lint (8.5) (push) Successful in 56s
Build package / xml-lint (push) Successful in 17s
Build package / unit-tests (push) Successful in 42s
Build package / package (push) Successful in 1m4s

The board list now only contains boards the current user owns, which
also makes the controller's board validation enforce the owner rule.

The workflow table gains a Board column (Board, Titel, Von Stapel,
Nach Stapel, Filter, E-Mail, Aktiv) and is sorted alphabetically by
those columns in that order.
This commit is contained in:
Patrick Niebeling committed 2026-09-30 09:16:09 +02:00
1 parent 7c7c52cb1c
commit ada16cb101
4 files changed
+85 -22

No files matched your search

+64 -13
View File
@@ -14,6 +14,7 @@
<table v-if="workflows.length" class="wfda-table">
<thead>
<tr>
<th>Board</th>
<th>Titel</th>
<th>Von Stapel</th>
<th>Nach Stapel</th>
@@ -24,7 +25,8 @@
</tr>
</thead>
<tbody>
<tr v-for="workflow in workflows" :key="workflow.id">
<tr v-for="workflow in sortedWorkflows" :key="workflow.id">
<td>{{ boardLabel(workflow.boardId) }}</td>
<td>
{{ workflow.title }}
<span v-if="workflowIssues[workflow.id]" class="wfda-issue">
@@ -33,16 +35,9 @@
</td>
<td>{{ stackLabel(workflow.boardId, workflow.sourceStackId) }}</td>
<td>{{ stackLabel(workflow.boardId, workflow.targetStackId) }}</td>
<td>
<span v-if="!workflow.filterUserIds.length && !workflow.filterLabelIds.length">–</span>
<span v-else>
<span v-if="workflow.filterUserIds.length">{{ workflow.filterUserIds.length }} Benutzer</span>
<span v-if="workflow.filterUserIds.length && workflow.filterLabelIds.length">, </span>
<span v-if="workflow.filterLabelIds.length">{{ workflow.filterLabelIds.length }} Label</span>
</span>
</td>
<td>{{ workflow.notifyEmail ? 'Ja' : 'Nein' }}</td>
<td>{{ workflow.enabled ? 'Ja' : 'Nein' }}</td>
<td>{{ filterLabel(workflow) }}</td>
<td>{{ yesNo(workflow.notifyEmail) }}</td>
<td>{{ yesNo(workflow.enabled) }}</td>
<td class="wfda-actions">
<NcButton variant="tertiary" @click="editWorkflow(workflow)">
Bearbeiten
@@ -75,6 +70,9 @@
:reduce="option => option.value"
placeholder="Board wählen"
@update:model-value="onBoardChange" />
<NcNoteCard v-if="!boardOptions.length" type="info">
Workflows können nur für Boards angelegt werden, deren Eigentümer du bist.
</NcNoteCard>
<NcSelect
v-model="form.sourceStackId"
@@ -175,7 +173,40 @@ const participantOptions = ref([])
// Which board the three lists above currently belong to.
const loadedBoardId = ref(null)
const boardOptions = computed(() => boards.value.map((board) => ({ value: board.id, label: board.title })))
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })
// The backend only returns boards the user owns.
const boardOptions = computed(() => boards.value
.map((board) => ({ value: board.id, label: board.title }))
.sort((a, b) => collator.compare(a.label, b.label)))
/**
* Alphabetical by the columns as displayed, left to right: board, title,
* source stack, target stack, filter, e-mail, active.
*/
const sortedWorkflows = computed(() => {
const sortKeys = (workflow) => [
boardLabel(workflow.boardId),
workflow.title,
stackLabel(workflow.boardId, workflow.sourceStackId),
stackLabel(workflow.boardId, workflow.targetStackId),
filterLabel(workflow),
yesNo(workflow.notifyEmail),
yesNo(workflow.enabled),
]
return workflows.value
.map((workflow) => ({ workflow, keys: sortKeys(workflow) }))
.sort((a, b) => {
for (let i = 0; i < a.keys.length; i++) {
const result = collator.compare(a.keys[i], b.keys[i])
if (result !== 0) {
return result
}
}
return a.workflow.id - b.workflow.id
})
.map((entry) => entry.workflow)
})
// Source and target must differ, so each dropdown hides what the other one
// already holds — the error message on save stays as the backstop for
@@ -199,7 +230,7 @@ const workflowIssues = computed(() => {
for (const workflow of workflows.value) {
if (!boards.value.some((board) => board.id === workflow.boardId)) {
issues[workflow.id] = 'Board nicht mehr vorhanden'
issues[workflow.id] = 'Board nicht mehr vorhanden oder nicht dein eigenes'
continue
}
@@ -262,6 +293,26 @@ function emptyForm() {
}
}
function boardLabel(boardId) {
const board = boards.value.find((entry) => entry.id === boardId)
return board ? board.title : `#${boardId}`
}
function filterLabel(workflow) {
const parts = []
if (workflow.filterUserIds.length) {
parts.push(`${workflow.filterUserIds.length} Benutzer`)
}
if (workflow.filterLabelIds.length) {
parts.push(`${workflow.filterLabelIds.length} Label`)
}
return parts.length ? parts.join(', ') : '–'
}
function yesNo(value) {
return value ? 'Ja' : 'Nein'
}
function stackLabel(boardId, stackId) {
const stacks = stacksByBoard[boardId]
if (!stacks) {