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

fix(#9601): prototype duplicate prevention #9609

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
"eurodigit": "^3.1.3",
"font-awesome": "^4.7.0",
"jquery": "3.5.1",
"levenshtein": "1.0.5",
"@types/levenshtein": "1.0.4",
"lodash-es": "^4.17.21",
"moment-locales-webpack-plugin": "^1.2.0",
"ngrx-store-logger": "^0.2.4",
Expand Down
5 changes: 5 additions & 0 deletions webapp/src/ts/components/enketo/enketo.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<div [attr.id]="formId" class="enketo" [attr.data-editing]="editing">
<div class="container pages"></div>
<!-- Do not use inline styling -->
<div
id="duplicate_info"
style="display: none; width: 100%; min-height: 20px; padding-left: 20px; padding-right: 20px; background-color: #ffe7e8; color: #e33030;">
</div>
<div class="form-footer">
<button (click)="onCancel.emit()" class="btn btn-link cancel" [disabled]="status?.saving">{{'Cancel' | translate}}</button>
<div class="loader inline small" *ngIf="status?.saving"></div>
Expand Down
17 changes: 17 additions & 0 deletions webapp/src/ts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ window.startupTimes.firstCodeExecution = performance.now();

window.PouchDB = require('pouchdb-browser').default;
window.$ = window.jQuery = require('jquery');
window._phdcChanges = {
hierarchyDuplicatePrevention: {
health_center: {
...Levenshtein,
props: [
{form_prop_path: `/data/health_center/name`, db_doc_ref: 'name'},
Copy link
Contributor

Choose a reason for hiding this comment

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

camelCase is the js standard.

{form_prop_path: '/data/health_center/external_id', db_doc_ref: 'external_id'}
],
queryParams: {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe formQuestion? Name is still bothering me.

valuePaths: ['/data/health_center/is_user_flagged_duplicate', '/data/health_center/duplicate/action'],
// eslint-disable-next-line eqeqeq
Copy link
Contributor

Choose a reason for hiding this comment

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

@jkuester Continuing to lobby for != as the most excellent exception to the strict equality lint rule. Checks for both null and undefined.

query: (duplicate, action) => duplicate === 'yes' && action != null
Copy link
Contributor

@fardarter fardarter Nov 13, 2024

Choose a reason for hiding this comment

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

@jkuester @ChinHairSaintClair My feeling here is that this would need to end up with some kind of operator syntax support that lets the user do logic, maybe something like (though doesn't have to be) JsonLogic: https://jsonlogic.com/

The way I see it there are two point of config -- the excel files and the configuration json -- and probably neither should take serialised JS (?).

If we return the key => { key, value } as a tuple or object on key lookup, we could let the user express logic maybe like this (with the value found at the key tested against the value provided (with) using the operator):

let andOnly = {
  logic: [
    [
      // array bracket denotes a logical grouping
      {
        key1: { with: value, op: $in },
        key2: { with: value, op: $contains },
        key3: { with: value, op: $eq },
      },
      {
        key1: { with: value, op: $in },
        key2: { with: value, op: $ne },
        key3: { with: value, op: $startsWith },
      },
    ],
  ],
};

let orWithNestedAnds = {
  logic: [
    [
      {
        key1: { with: value, op: $in },
      },
      {
        key2: { with: value, op: $eq },
      },
    ],
    // each grouping in its own bracket
    [
      {
        key1: { with: value, op: $in },
      },
      {
        key2: { with: value, op: $in },
      },
    ],
  ],
};

let orWithNestedOrWithNestedAnds = {
  logic: [
    [
      {
        key1: { with: value, op: $in },
      },
      {
        key2: { with: value, op: $in },
      },
    ],
    // OR
    [
      [
        // nested groupings acceptable
        {
          key1: { with: value, op: $ne },
        },
        // AND
        {
          key2: { with: value, op: $ne },
        },
      ],
      // OR
      [
        {
          key1: { with: value, op: $contains },
        },
        // AND
        {
          key1: { with: value, op: $startsWith },
        },
      ],
    ],
  ],
};

The other stuff seems easier to move to config.

}
}
}
};

import { enableProdMode } from '@angular/core';
import '@angular/compiler';
Expand All @@ -19,6 +35,7 @@ import { environment } from '@mm-environments/environment';
import { POUCHDB_OPTIONS } from './constants';

import * as bootstrapper from '../js/bootstrapper';
import { Levenshtein } from './polyfills';

// Moment additional locales
require('../js/moment-locales/tl');
Expand Down
Loading
Loading