Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] DV, CF: Enforce range on CF & DV #5679

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fdamhaut
Copy link
Contributor

Description:

Enforce that the ranges on CF & DV belong to the same sheet they do.

Task: 4072640

review checklist

  • feature is organized in plugin, or UI components
  • support of duplicate sheet (deep copy)
  • in model/core: ranges are Range object, and can be adapted (adaptRanges)
  • in model/UI: ranges are strings (to show the user)
  • undo-able commands (uses this.history.update)
  • multiuser-able commands (has inverse commands and transformations where needed)
  • new/updated/removed commands are documented
  • exportable in excel
  • translations (_t("qmsdf %s", abc))
  • unit tested
  • clean commented code
  • track breaking changes
  • doc is rebuild (npm run doc)
  • status is correct in Odoo

@robodoo
Copy link
Collaborator

robodoo commented Feb 10, 2025

Pull request status dashboard

@fdamhaut fdamhaut force-pushed the master-spreadsheet-dv-cf-range-enforcement-flda branch from e51aea4 to b30c4c3 Compare February 10, 2025 16:03
Copy link
Contributor

@hokolomopo hokolomopo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pouet pouet 🎺

Comment on lines 255 to 262
const ranges = rangesXC.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc));
const OOSranges = ranges.some((range) => range._sheetId != sheetId);
if (OOSranges) {
if (!newCf.suppressErrors) {
this.state.errors = [CommandResult.TargetOutOfSheet];
}
return [CommandResult.TargetOutOfSheet];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be handled in the allowDispatch of the core plugin, not here (like the data validations)

@@ -28,6 +28,7 @@ export const CfTerms = {
[CommandResult.ValueCellIsInvalidFormula]: _t(
"At least one of the provided values is an invalid formula"
),
[CommandResult.TargetOutOfSheet]: _t("The range cannot target out of the current sheet."),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message isn't very clear IMO. Since we can leave the side panel open while changing sheet, talking about current sheet is dubious. "The range" when there is no clear way to know about which range we are talking about is also not very clear.

"All the ranges should be in the same sheet as the conditional format" maybe ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still valid, the message
image

does not seems very english/clear. Maybe it's just me. And we should probably put the range between quotes.

@@ -198,6 +200,7 @@ export class ConditionalFormattingEditor extends Component<Props, SpreadsheetChi
setup() {
this.state = useState<State>({
errors: [],
sheetId: this.env.model.getters.getActiveSheetId(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theoretically we could open the CF editor pane on a CF that is not on the active sheet. sheetId should probably be a props.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not addressed

- Enforce that the target range of CF & DV belong to the same
sheet than them
- Allow to switch sheet while editing CF to set formulas

task: 4072640
@fdamhaut fdamhaut force-pushed the master-spreadsheet-dv-cf-range-enforcement-flda branch from b30c4c3 to f360106 Compare February 19, 2025 14:21
Copy link
Contributor

@hokolomopo hokolomopo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

get firstInvalidRangeString(): string | undefined {
const sheetId = this.sheetId;
return this.state.ranges.find((xc) => {
const range = this.env.model.getters.getRangeDataFromXc(sheetId, xc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const range = this.env.model.getters.getRangeDataFromXc(sheetId, xc);
const range = this.env.model.getters.getRangeFromSheetXc(sheetId, xc);

don't use RangeData when you do'nt have to. They are a bit ugly, and only meant for commands. We shouldn't want to access range._sheetId, it's "private"

case CommandResult.InvalidRange:
return CfTerms.Errors[reason](this.firstInvalidRangeString);
case CommandResult.ValueCellIsInvalidFormula:
return CfTerms.Errors[reason](this.firstInvalidFormula);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really necessary, the composer is already highlighted red to show the user it's invalid.

And the message only displays the first invalid formula, but there could be multiple. Either make a message for every invalid formula, or don't bother making a dynamic message.

Comment on lines +17 to +19
[CommandResult.MinBiggerThanMax]: () => _t("Minimum must be smaller then Maximum"),
[CommandResult.MinBiggerThanMid]: () => _t("Minimum must be smaller then Midpoint"),
[CommandResult.MidBiggerThanMax]: () => _t("Midpoint must be smaller then Maximum"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while you're changing this: you could fix the message. "than" rather than "then". And remove random uppercasing of words

Comment on lines +147 to 150
this.checkEmptyRange,
this.checkValidRange,
this.checkCFRule,
this.checkEmptyRange,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.checkEmptyRange is there twice

Comment on lines +399 to +402
const stringRanges = ranges.map((range) => this.getters.getRangeString(range, cmd.sheetId));
if (stringRanges.some((xc) => !this.getters.isRangeValid(xc))) {
return CommandResult.InvalidRange;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably wrong way to do that/useless. We're coming from a RangeData, so either it's a normal rangeData and the XC will always be valid, or it's really malformed and the conversion to range/string will throw and we'll never return CommandResult.InvalidRange.

And we already test for invalid zones inside the sheet core plugin.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh you copied what was already in the data validation. Well either i'm wrong and there is cases where you return CommandResult.InvalidRange here, or you can remove it from both.

setInputValueAndTrigger(selectors.ruleEditor.range, "Sheet2!A1");

const dispatch = spyModelDispatch(model);
// click save
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: comment looks useless

createSheet(model, { sheetId: "ID", name: "Sheet2", activate: false });
await simulateClick(".o-dv-add");
await nextTick();
await changeCriterionType("dateIs");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless no ?

@@ -18,7 +18,7 @@ mockGetBoundingClientRect({
"o-dv-type": () => dataValidationSelectBoundingRect,
});

export async function mountDataValidationPanel(model?: Model) {
async function mountDataValidationPanel(model?: Model) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this and use the new helper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants