Skip to content

Commit 22960ea

Browse files
committed
Fix: Properly display removed options in selection columns
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
1 parent 3f67752 commit 22960ea

6 files changed

Lines changed: 105 additions & 94 deletions

File tree

src/shared/components/ncTable/mixins/columnsTypes/selection.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@ export default class SelectionColumn extends AbstractSelectionColumn {
2020
}
2121

2222
getLabel(id) {
23-
const i = this.selectionOptions?.findIndex((obj) => obj.id === id)
24-
return this.selectionOptions[i]?.label
23+
return this.getOptionObject(id)?.label
2524
}
2625

27-
isDeletedLabel(value) {
28-
const i = this.selectionOptions?.findIndex((obj) => obj.id === value)
29-
return !!this.selectionOptions[i]?.deleted
26+
getOptionObject(id) {
27+
if (id === null || id === undefined) return null
28+
return this.selectionOptions?.find((obj) => obj.id === id) || { id, label: String(id), deleted: true }
3029
}
3130

3231
sort(mode, nextSorts) {

src/shared/components/ncTable/mixins/columnsTypes/selectionMulti.js

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,15 @@ export default class SelectionMutliColumn extends AbstractSelectionColumn {
4141
}
4242

4343
getObjects(values) {
44-
// values is an array of option-ids as string
45-
const objects = []
46-
values?.forEach(id => {
47-
const optionsObject = this.getOptionObject(parseInt(id))
48-
// skip options that not exists anymore
49-
if (optionsObject) {
50-
objects.push(optionsObject)
51-
}
52-
})
53-
return objects
44+
return (values || [])
45+
.map(rawId => parseInt(rawId))
46+
.filter(id => !Number.isNaN(id))
47+
.map(id => this.getOptionObject(id))
5448
}
5549

5650
getOptionObject(id) {
57-
const i = this.selectionOptions?.findIndex(obj => {
58-
return obj.id === id
59-
})
60-
if (i !== undefined) {
61-
return this.selectionOptions[i] || null
62-
}
51+
if (id === null || id === undefined) return null
52+
return this.selectionOptions?.find(obj => obj.id === id) || { id, label: String(id), deleted: true }
6353
}
6454

6555
isSearchStringFound(cell, searchString) {

src/shared/components/ncTable/partials/TableCellMultiSelection.vue

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
<div class="cell-multi-selection" :style="{ opacity: !canEditCell() ? 0.6 : 1 }">
77
<div v-if="!isEditing" class="non-edit-mode" @click="handleStartEditing">
88
<ul>
9-
<li v-for="v in getObjects()" :key="v.id">
10-
{{ v.label }}<span v-if="v.deleted" :title="t('tables', 'This option is outdated.')">&nbsp;⚠️</span>
9+
<li v-for="v in displayObjects" :key="v.id">
10+
<span v-if="v.deleted" class="outdated-option-label">{{ v.label }}&nbsp;<span
11+
class="outdated-option-indicator"
12+
:title="t('tables', 'This option is outdated.')">⚠️</span></span>
13+
<span v-else>{{ v.label }}</span>
1114
</li>
1215
</ul>
1316
</div>
@@ -19,7 +22,8 @@
1922
@keydown.escape.stop="cancelEdit">
2023
<NcSelect v-model="editValues"
2124
:tag-width="80"
22-
:options="getAllNonDeletedOrSelectedOptions"
25+
:options="selectableOptions"
26+
:selectable="option => !option?.deleted"
2327
:clearable="!column.mandatory"
2428
:multiple="true"
2529
:aria-label-combobox="t('tables', 'Options')"
@@ -71,20 +75,22 @@ export default {
7175
},
7276
7377
computed: {
74-
getOptions() {
78+
options() {
7579
return this.column.selectionOptions || []
7680
},
77-
getAllNonDeletedOrSelectedOptions() {
78-
const options = this.getOptions.filter(item => {
79-
return !item.deleted || this.optionIdIsSelected(item.id)
80-
}) || []
81-
82-
options.forEach(opt => {
83-
if (opt.deleted) {
84-
opt.label += ' ⚠️'
85-
}
86-
})
87-
return options
81+
selectedOptionIds() {
82+
return (this.value || [])
83+
.map(item => parseInt(item))
84+
.filter(id => !Number.isNaN(id))
85+
},
86+
selectableOptions() {
87+
const missingOptions = this.selectedOptionIds
88+
.map(id => this.column.getOptionObject(id))
89+
.filter(opt => opt.deleted)
90+
return [...this.options, ...missingOptions]
91+
},
92+
displayObjects() {
93+
return this.selectedOptionIds.map(id => this.column.getOptionObject(id))
8894
},
8995
editValues: {
9096
get() {
@@ -122,15 +128,6 @@ export default {
122128
event.stopPropagation()
123129
},
124130
125-
getObjects() {
126-
return this.column.getObjects(this.value)
127-
},
128-
129-
optionIdIsSelected(id) {
130-
// Check if the given id is selected (in the value array)
131-
return this.value && this.value.includes(id)
132-
},
133-
134131
getIdArrayFromObjects(objects) {
135132
const ids = []
136133
objects.forEach(o => {
@@ -141,7 +138,7 @@ export default {
141138
142139
initEditValues() {
143140
if (this.value !== null) {
144-
this.localEditValues = this.column.getObjects(this.value)
141+
this.localEditValues = this.displayObjects
145142
} else {
146143
this.localEditValues = []
147144
}
@@ -215,4 +212,12 @@ ul {
215212
list-style-type: disc;
216213
padding-inline-start: calc(var(--default-grid-baseline) * 3);
217214
}
215+
216+
.outdated-option-indicator {
217+
cursor: help;
218+
}
219+
220+
.outdated-option-label {
221+
opacity: 0.6;
222+
}
218223
</style>

src/shared/components/ncTable/partials/TableCellSelection.vue

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
<template>
66
<div class="cell-selection">
77
<div v-if="!isEditing" class="non-edit-mode" @click="handleStartEditing">
8-
{{ column.getLabel(value) }}<span v-if="isDeleted()" :title="t('tables', 'This option is outdated.')">&nbsp;⚠️</span>
8+
<span v-if="isRemovedOption" class="outdated-option-label">{{ selectedOptionId }}</span><span v-if="isRemovedOption"
9+
class="outdated-option-indicator"
10+
:title="t('tables', 'This option is outdated.')">&nbsp;⚠️</span>
11+
<span v-else>{{ selectedOption?.label }}</span>
912
</div>
1013
<div v-else
1114
ref="editingContainer"
@@ -14,7 +17,8 @@
1417
@keydown.enter.stop="saveChanges"
1518
@keydown.escape.stop="cancelEdit">
1619
<NcSelect v-model="editValue"
17-
:options="getAllNonDeletedOptions"
20+
:options="selectableOptions"
21+
:selectable="option => !option?.deleted"
1822
:clearable="!column.mandatory"
1923
:aria-label-combobox="t('tables', 'Options')"
2024
:disabled="localLoading || !canEditCell()"
@@ -64,13 +68,27 @@ export default {
6468
},
6569
6670
computed: {
67-
getOptions() {
71+
options() {
6872
return this.column?.selectionOptions || []
6973
},
70-
getAllNonDeletedOptions() {
71-
return this.getOptions.filter(item => {
72-
return !item.deleted
73-
})
74+
selectedOptionId() {
75+
const optionId = parseInt(this.value)
76+
return Number.isNaN(optionId) ? null : optionId
77+
},
78+
selectedOption() {
79+
if (this.selectedOptionId === null) {
80+
return null
81+
}
82+
return this.column.getOptionObject(this.selectedOptionId)
83+
},
84+
selectableOptions() {
85+
if (this.selectedOption?.deleted) {
86+
return [...this.options, this.selectedOption]
87+
}
88+
return this.options
89+
},
90+
isRemovedOption() {
91+
return this.selectedOption?.deleted === true
7492
},
7593
},
7694
@@ -101,17 +119,9 @@ export default {
101119
event.stopPropagation()
102120
},
103121
104-
isDeleted() {
105-
return this.column.isDeletedLabel(this.value)
106-
},
107-
108-
getOptionObject(id) {
109-
return this.getOptions.find(e => e.id === id) || null
110-
},
111-
112122
initEditValue() {
113-
if (this.value !== null) {
114-
this.editValue = this.getOptionObject(parseInt(this.value))
123+
if (this.value !== null && this.value !== undefined) {
124+
this.editValue = this.selectedOption
115125
} else {
116126
this.editValue = null
117127
}
@@ -170,7 +180,11 @@ export default {
170180
}
171181
}
172182
173-
span {
183+
.outdated-option-indicator {
174184
cursor: help;
175185
}
186+
187+
.outdated-option-label {
188+
opacity: 0.6;
189+
}
176190
</style>

src/shared/components/ncTable/partials/rowTypePartials/SelectionForm.vue

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
<RowFormWrapper :title="column.title" :mandatory="isMandatory(column)" :description="column.description">
77
<NcSelect
88
v-model="localValue"
9-
:options="getAllNonDeletedOptions"
9+
:options="selectableOptions"
10+
:selectable="option => !option?.deleted"
1011
:clearable="!column.mandatory"
1112
:disabled="column.viewColumnInformation?.readonly"
1213
:aria-label-combobox="t('tables', 'Options')" />
@@ -38,7 +39,7 @@ export default {
3839
localValue: {
3940
get() {
4041
if (this.value !== null) {
41-
return this.getOptionObject(parseInt(this.value))
42+
return this.selectedOption
4243
} else {
4344
this.$emit('update:value', this.getDefaultId)
4445
return this.getDefaultOptionObject
@@ -47,23 +48,29 @@ export default {
4748
set(v) { this.$emit('update:value', v?.id) },
4849
},
4950
getOptions() {
50-
return this.column?.selectionOptions || null
51+
return this.column?.selectionOptions || []
5152
},
5253
getDefaultId() {
5354
return !isNaN(this.column.selectionDefault) ? parseInt(this.column.selectionDefault) : null
5455
},
5556
getDefaultOptionObject() {
56-
return this.getOptionObject(this.getDefaultId) || null
57+
return this.column.getOptionObject(this.getDefaultId)
5758
},
58-
getAllNonDeletedOptions() {
59-
return this.getOptions.filter(item => {
60-
return !item.deleted
61-
})
59+
selectedOptionId() {
60+
const optionId = parseInt(this.value)
61+
return Number.isNaN(optionId) ? null : optionId
6262
},
63-
},
64-
methods: {
65-
getOptionObject(id) {
66-
return this.getOptions.find(e => e.id === id) || null
63+
selectedOption() {
64+
if (this.selectedOptionId === null) {
65+
return null
66+
}
67+
return this.column.getOptionObject(this.selectedOptionId)
68+
},
69+
selectableOptions() {
70+
if (this.selectedOption?.deleted) {
71+
return [...this.getOptions, this.selectedOption]
72+
}
73+
return this.getOptions
6774
},
6875
},
6976
}

src/shared/components/ncTable/partials/rowTypePartials/SelectionMultiForm.vue

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
<NcSelect
88
v-model="localValues"
99
:tag-width="80"
10-
:options="getAllNonDeletedOrSelectedOptions"
10+
:options="selectableOptions"
11+
:selectable="option => !option?.deleted"
1112
:clearable="!column.mandatory"
1213
:disabled="column.viewColumnInformation?.readonly"
1314
:multiple="true"
@@ -40,7 +41,7 @@ export default {
4041
localValues: {
4142
get() {
4243
if (this.value !== null) {
43-
return this.column.getObjects(this.value)
44+
return this.selectedOptionIds.map(id => this.column.getOptionObject(id))
4445
} else {
4546
this.$emit('update:value', this.column.default())
4647
return this.column.getDefaultObjects()
@@ -51,26 +52,21 @@ export default {
5152
},
5253
},
5354
getOptions() {
54-
return this.column.selectionOptions || null
55+
return this.column.selectionOptions || []
5556
},
56-
getAllNonDeletedOrSelectedOptions() {
57-
const options = this.getOptions?.filter(item => {
58-
return !item.deleted || this.optionIdIsSelected(item.id)
59-
}) || []
60-
61-
options.forEach(opt => {
62-
if (opt.deleted) {
63-
opt.label += ' ⚠️'
64-
}
65-
})
66-
return options
57+
selectedOptionIds() {
58+
return (this.value || [])
59+
.map(item => parseInt(item))
60+
.filter(id => !Number.isNaN(id))
61+
},
62+
selectableOptions() {
63+
const missingOptions = this.selectedOptionIds
64+
.map(id => this.column.getOptionObject(id))
65+
.filter(opt => opt.deleted)
66+
return [...this.getOptions, ...missingOptions]
6767
},
6868
},
6969
methods: {
70-
optionIdIsSelected(id) {
71-
// check if the given id is selected (in the value array)
72-
return this.values.includes(id)
73-
},
7470
getIdArrayFromObjects(objects) {
7571
const ids = []
7672
objects.forEach(o => {

0 commit comments

Comments
 (0)