Skip to content

Commit d7f542a

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

6 files changed

Lines changed: 106 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: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
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+
<template v-if="v.deleted">
11+
<span class="outdated-option-label">{{ v.label }}</span><span
12+
class="outdated-option-indicator"
13+
:title="t('tables', 'This option is outdated.')">⚠️</span>
14+
</template>
15+
<span v-else>{{ v.label }}</span>
1116
</li>
1217
</ul>
1318
</div>
@@ -19,7 +24,8 @@
1924
@keydown.escape.stop="cancelEdit">
2025
<NcSelect v-model="editValues"
2126
:tag-width="80"
22-
:options="getAllNonDeletedOrSelectedOptions"
27+
:options="selectableOptions"
28+
:selectable="option => !option?.deleted"
2329
:clearable="!column.mandatory"
2430
:multiple="true"
2531
:aria-label-combobox="t('tables', 'Options')"
@@ -71,20 +77,22 @@ export default {
7177
},
7278
7379
computed: {
74-
getOptions() {
80+
options() {
7581
return this.column.selectionOptions || []
7682
},
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
83+
selectedOptionIds() {
84+
return (this.value || [])
85+
.map(item => parseInt(item))
86+
.filter(id => !Number.isNaN(id))
87+
},
88+
selectableOptions() {
89+
const missingOptions = this.selectedOptionIds
90+
.map(id => this.column.getOptionObject(id))
91+
.filter(opt => opt.deleted)
92+
return [...this.options, ...missingOptions]
93+
},
94+
displayObjects() {
95+
return this.selectedOptionIds.map(id => this.column.getOptionObject(id))
8896
},
8997
editValues: {
9098
get() {
@@ -122,15 +130,6 @@ export default {
122130
event.stopPropagation()
123131
},
124132
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-
134133
getIdArrayFromObjects(objects) {
135134
const ids = []
136135
objects.forEach(o => {
@@ -141,7 +140,7 @@ export default {
141140
142141
initEditValues() {
143142
if (this.value !== null) {
144-
this.localEditValues = this.column.getObjects(this.value)
143+
this.localEditValues = this.displayObjects
145144
} else {
146145
this.localEditValues = []
147146
}
@@ -215,4 +214,12 @@ ul {
215214
list-style-type: disc;
216215
padding-inline-start: calc(var(--default-grid-baseline) * 3);
217216
}
217+
218+
.outdated-option-indicator {
219+
cursor: help;
220+
}
221+
222+
.outdated-option-label {
223+
opacity: 0.6;
224+
}
218225
</style>

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

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
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+
<template v-if="selectedOption.deleted">
9+
<span class="outdated-option-label">{{ selectedOptionId }}</span><span
10+
class="outdated-option-indicator"
11+
:title="t('tables', 'This option is outdated.')">⚠️</span>
12+
</template>
13+
<span v-else>{{ selectedOption?.label }}</span>
914
</div>
1015
<div v-else
1116
ref="editingContainer"
@@ -14,7 +19,8 @@
1419
@keydown.enter.stop="saveChanges"
1520
@keydown.escape.stop="cancelEdit">
1621
<NcSelect v-model="editValue"
17-
:options="getAllNonDeletedOptions"
22+
:options="selectableOptions"
23+
:selectable="option => !option?.deleted"
1824
:clearable="!column.mandatory"
1925
:aria-label-combobox="t('tables', 'Options')"
2026
:disabled="localLoading || !canEditCell()"
@@ -64,13 +70,24 @@ export default {
6470
},
6571
6672
computed: {
67-
getOptions() {
73+
options() {
6874
return this.column?.selectionOptions || []
6975
},
70-
getAllNonDeletedOptions() {
71-
return this.getOptions.filter(item => {
72-
return !item.deleted
73-
})
76+
selectedOptionId() {
77+
const optionId = parseInt(this.value)
78+
return Number.isNaN(optionId) ? null : optionId
79+
},
80+
selectedOption() {
81+
if (this.selectedOptionId === null) {
82+
return null
83+
}
84+
return this.column.getOptionObject(this.selectedOptionId)
85+
},
86+
selectableOptions() {
87+
if (this.selectedOption?.deleted) {
88+
return [...this.options, this.selectedOption]
89+
}
90+
return this.options
7491
},
7592
},
7693
@@ -101,17 +118,9 @@ export default {
101118
event.stopPropagation()
102119
},
103120
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-
112121
initEditValue() {
113-
if (this.value !== null) {
114-
this.editValue = this.getOptionObject(parseInt(this.value))
122+
if (this.value !== null && this.value !== undefined) {
123+
this.editValue = this.selectedOption
115124
} else {
116125
this.editValue = null
117126
}
@@ -170,7 +179,11 @@ export default {
170179
}
171180
}
172181
173-
span {
182+
.outdated-option-indicator {
174183
cursor: help;
175184
}
185+
186+
.outdated-option-label {
187+
opacity: 0.6;
188+
}
176189
</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)