Bug 10190: (QA follow-up): fix: prevent delay-less rule sets

Since the decision was made that the add / edit trigger form should
never let a trigger be created or edited to not have a delay, it
follows that this must apply to the rule set reset flow as well.

Retain the warning message to the user, and also disable the
'Confirm reset' button if the reset would result in delay-less
sets.

The same applies to the trigger deletion functionality: if deleting
a trigger that is a default for all libraries would then leave any
libraries with one or more delay-less rule set, block the trigger
deletion (deactivate 'Confirm deletion') and inform the user. Here
as well we also still display the warning message.

Test plan:

A) Create one or more 'Default for all libraries' triggers.
B) Create one or more library-specific triggers.
C) For one or more of these, add itemtype and/or category specific overrides with not delay override.
D) For one or more of these, add itemtype and/or category specific overrides with a delay override.
E) Select 'Reset' on a rule set with overrides of type D) and notice that the 'Confirm reset' button is enabled.
F) Select 'Reset' on a rule set with overrides of type C) and notice that the 'Confirm reset' button is disabled,
    and that the warning message explains why reset is unavailable
G) Select 'Delete' on the highest 'Default for all libraries' trigger, and notice that, where one or more library-specific overrides are of type D), 'Confirm deletion' is disabled, whereas it is otherwise enabled.
H) Delete a trigger for which no override exists and confirm success.
I) Delete a trigger for which only type D) overrides exist and confirm success.
J) Reset a rule set for which only type D) overrides exist and confirm success.
K) Reset a rule set for which no override exists and confirm success.

Assisted-by: Claude Opus 5 (Anthropic)
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Chloé Zermatten 2026-09-03 11:24:20 +00:00 committed by Pedro Amorim
parent b38d6d5201
commit 99442e36b3
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
3 changed files with 40 additions and 2 deletions

View File

@ -20,7 +20,7 @@
<slot></slot>
</div>
<div class="modal-footer">
<ButtonSubmit :title="buttonText" />
<ButtonSubmit :title="buttonText" :disabled="disabled" />
<router-link
:to="{
name: 'CirculationTriggersList',
@ -33,7 +33,7 @@
<script>
import ButtonSubmit from "../../ButtonSubmit.vue";
export default {
props: ["submitAction", "formTitle", "buttonText"],
props: ["submitAction", "formTitle", "buttonText", "disabled"],
components: { ButtonSubmit },
};
</script>

View File

@ -3,6 +3,7 @@
:submitAction="resetCircRules"
formTitle="Confirm circulation rule set reset"
buttonText="Confirm reset"
:disabled="resetWouldLeaveRuleSetWithoutDelay"
>
<TriggersTable
v-if="initialized"
@ -102,6 +103,18 @@ export default {
await vm.loadModalData();
});
},
computed: {
// a trigger with no delay is never processed, so a reset that would
// leave an inheriting set without one is not allowed
resetWouldLeaveRuleSetWithoutDelay() {
const delayName = `overdue_${this.triggerNumber}_delay`;
return this.projectedDependentEffectiveRuleSets.some(
ruleSet =>
ruleSet[delayName]?.value === "" ||
ruleSet[delayName]?.value == null
);
},
},
methods: {
async loadModalData() {
await this.setAllFormattedRuleSets();
@ -134,6 +147,12 @@ export default {
);
}
if (this.resetWouldLeaveRuleSetWithoutDelay) {
this.alertMessage = this.$__(
"This rule set cannot be reset. One or more sets that inherit from it would be left without a delay, which stops that trigger and every higher numbered trigger from being processed. See the preview below."
);
}
this.initialized = true;
},
async resetCircRules(e) {

View File

@ -7,6 +7,7 @@
: 'Confirm circulation trigger deletion'
"
buttonText="Confirm deletion"
:disabled="deletionWouldLeaveRuleSetWithoutDelay"
>
<fieldset class="rows">
<TriggersTable
@ -106,6 +107,18 @@ export default {
await vm.loadModalData();
});
},
computed: {
// a trigger with no delay is never processed, so a deletion that would
// leave an inheriting set without one is not allowed
deletionWouldLeaveRuleSetWithoutDelay() {
const delayName = `overdue_${this.triggerNumber}_delay`;
return this.projectedDependentEffectiveRuleSets.some(
ruleSet =>
ruleSet[delayName]?.value === "" ||
ruleSet[delayName]?.value == null
);
},
},
methods: {
async loadModalData() {
await this.setAllFormattedRuleSets();
@ -129,6 +142,12 @@ export default {
);
}
if (this.deletionWouldLeaveRuleSetWithoutDelay) {
this.alertMessage = this.$__(
"This trigger cannot be deleted. One or more sets that inherit from it would be left without a delay, which stops that trigger and every higher numbered trigger from being processed. See the preview below."
);
}
this.initialized = true;
},
async deleteTrigger(e) {