Bug 10190: (QA follow-up) Fix six issues reported during QA
1. Letter context: setFilteredLetters() was reading library_id from currentRuleSet (which has no top-level library_id property) instead of this.context.library_id, causing library-specific letter templates to never match. 2. False conflict on edit: conflict check fetched rule set from DB with effective=false (raw), but the in-memory snapshot was fetched with effective=true (with fallbacks). Comparing raw vs effective always triggered a conflict when a context inherited any value from a more general rule. Fixed by using effective=true for the DB fetch too. 3. Incomplete deletion: updateCircRuleSets() inside deleteRuleSet() was called without await, creating a race condition where the page refresh could complete before the deletion API call, leaving stale data visible. Also added a guard to skip rule sets with no explicit rules for the trigger being deleted, and simplified rulesForDeletion construction. 4. No rules displayed on initial load: the route watcher in CirculationTriggersList fired immediately before init() had loaded patron categories and item types, causing setAllExhaustiveEffectiveRuleSets() to produce an empty result. Fixed with a metaInitialized flag that the watcher waits for before proceeding. 5. DefaultToLoggedInLibraryOverdueTriggers syspref not respected: the default_view template variable was computed but never applied to the store's currentLibraryId. Fixed by passing it to init(). 6. UI colors: info box background changed from #84c1f3 to #DAECFB (lighter, matching the circulation rules page). Error alert messages changed from alert-info (blue) to alert-warning (yellow) to match Koha conventions. Signed-off-by: Michaela <michaela.sieber@kit.edu> Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
8f6cee51ea
commit
14fe8cb2f5
|
|
@ -126,7 +126,7 @@
|
|||
<p>{{ $__("Loading context...") }}</p>
|
||||
</div>
|
||||
<fieldset class="rows" v-if="alertMessage">
|
||||
<div class="alert alert-info">{{ alertMessage }}</div>
|
||||
<div class="alert alert-warning">{{ alertMessage }}</div>
|
||||
</fieldset>
|
||||
<fieldset
|
||||
class="rows"
|
||||
|
|
@ -601,7 +601,10 @@ export default {
|
|||
|
||||
// in edit mode, check for changes from elsewhere to the rule set being edited
|
||||
if (this.editMode === "edit") {
|
||||
const ruleSetInDb = await this.getSelectedRuleSet(this.context);
|
||||
const ruleSetInDb = await this.getSelectedRuleSet(
|
||||
this.context,
|
||||
true
|
||||
);
|
||||
if (
|
||||
this.hasConflict(
|
||||
ruleSetInDb,
|
||||
|
|
@ -756,7 +759,7 @@ export default {
|
|||
: Infinity;
|
||||
},
|
||||
setFilteredLetters() {
|
||||
const library = this.currentRuleSet.library_id;
|
||||
const library = this.context.library_id;
|
||||
const byCode = new Map();
|
||||
|
||||
for (const letter of this.letters) {
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@
|
|||
</fieldset>
|
||||
|
||||
<fieldset class="rows" v-if="alertMessage">
|
||||
<div class="alert alert-info">{{ alertMessage }}</div>
|
||||
<div class="alert alert-warning">{{ alertMessage }}</div>
|
||||
</fieldset>
|
||||
</CirculationTriggersForm>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="alert alert-info" v-if="alertMessage">
|
||||
<div class="alert alert-warning" v-if="alertMessage">
|
||||
{{ alertMessage }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ export default {
|
|||
allEffectiveRuleSets,
|
||||
librariesWithRules,
|
||||
storeInitialized,
|
||||
metaInitialized,
|
||||
} = storeToRefs(circRulesStore);
|
||||
|
||||
return {
|
||||
|
|
@ -372,6 +373,7 @@ export default {
|
|||
isLastTrigger,
|
||||
getLibrariesWithRules,
|
||||
storeInitialized,
|
||||
metaInitialized,
|
||||
from_branch,
|
||||
};
|
||||
},
|
||||
|
|
@ -483,6 +485,19 @@ export default {
|
|||
this.$route.fullPath.includes("refresh") ||
|
||||
this.$route.path.endsWith("circulation_triggers")
|
||||
) {
|
||||
if (!this.metaInitialized) {
|
||||
await new Promise(resolve => {
|
||||
const stop = this.$watch(
|
||||
"metaInitialized",
|
||||
val => {
|
||||
if (val) {
|
||||
stop();
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
await this.$nextTick();
|
||||
await this.filterRuleSetsbySearchParam();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { inject } from "vue";
|
|||
export default {
|
||||
setup() {
|
||||
const circRulesStore = inject("circRulesStore");
|
||||
circRulesStore.init();
|
||||
circRulesStore.init(default_view);
|
||||
letters.unshift({
|
||||
name: "No letter",
|
||||
code: "",
|
||||
|
|
@ -51,6 +51,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.page-section.bg-info {
|
||||
background-color: #DAECFB !important;
|
||||
}
|
||||
|
||||
form .v-select {
|
||||
display: inline-block;
|
||||
background-color: white;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export const useCircRulesStore = defineStore("circRules", () => {
|
|||
currentPatronCategoryId: null,
|
||||
currentItemTypeId: null,
|
||||
triggerCounts: { "*": 0 },
|
||||
metaInitialized: false,
|
||||
// references
|
||||
itemTypes: [],
|
||||
libraries: [],
|
||||
|
|
@ -44,10 +45,12 @@ export const useCircRulesStore = defineStore("circRules", () => {
|
|||
|
||||
const actions = {
|
||||
// controllers
|
||||
async init() {
|
||||
async init(defaultLibraryId = "*") {
|
||||
await this.getItemTypes();
|
||||
await this.getLibraries();
|
||||
await this.getPatronCategories();
|
||||
this.currentLibraryId = defaultLibraryId;
|
||||
this.metaInitialized = true;
|
||||
},
|
||||
async loadUserPermissions() {
|
||||
if (this.userPermissions !== null) {
|
||||
|
|
@ -390,27 +393,24 @@ export const useCircRulesStore = defineStore("circRules", () => {
|
|||
},
|
||||
// repositories
|
||||
async deleteRuleSet(ruleSet, triggerNumber) {
|
||||
if (!this.hasExplicitRulesForTrigger(ruleSet, triggerNumber)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ruleSetInDb = await this.getSelectedRuleSet(ruleSet.context);
|
||||
|
||||
if (this.hasConflict(ruleSet, ruleSetInDb, triggerNumber)) {
|
||||
throw "The rule set for the selected trigger context could not be reset as it was updated elsewhere. Please see the updated trigger above.";
|
||||
}
|
||||
|
||||
const rulesForDeletion = { context: ruleSet.context };
|
||||
|
||||
if (ruleSet[`overdue_${triggerNumber}_delay`] !== null) {
|
||||
rulesForDeletion[`overdue_${triggerNumber}_delay`] = null;
|
||||
}
|
||||
if (ruleSet[`overdue_${triggerNumber}_notice`] !== null) {
|
||||
rulesForDeletion[`overdue_${triggerNumber}_notice`] = null;
|
||||
}
|
||||
if (ruleSet[`overdue_${triggerNumber}_restrict`] !== null) {
|
||||
rulesForDeletion[`overdue_${triggerNumber}_restrict`] = null;
|
||||
}
|
||||
if (ruleSet[`overdue_${triggerNumber}_mtt`] !== null) {
|
||||
rulesForDeletion[`overdue_${triggerNumber}_mtt`] = null;
|
||||
}
|
||||
this.updateCircRuleSets(rulesForDeletion, triggerNumber);
|
||||
const rulesForDeletion = {
|
||||
context: ruleSet.context,
|
||||
[`overdue_${triggerNumber}_delay`]: null,
|
||||
[`overdue_${triggerNumber}_notice`]: null,
|
||||
[`overdue_${triggerNumber}_restrict`]: null,
|
||||
[`overdue_${triggerNumber}_mtt`]: null,
|
||||
};
|
||||
await this.updateCircRuleSets(rulesForDeletion, triggerNumber);
|
||||
},
|
||||
async getLibrariesWithRules() {
|
||||
const client = APIClient.circRule;
|
||||
|
|
|
|||
Loading…
Reference in New Issue