Skip to content

Commit

Permalink
feat(FSADT1-1396): added fuzzy matching for registered business
Browse files Browse the repository at this point in the history
  • Loading branch information
paulushcgcj committed Aug 14, 2024
1 parent 808ae4b commit 89e6a63
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 100 deletions.
5 changes: 4 additions & 1 deletion frontend/src/assets/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,10 @@ cds-textarea::part(label), .cds-text-input-label {
color: var(--light-theme-text-text-primary, #131315);
}

cds-text-input.warning::part(input) {
cds-text-input.warning::part(input),
cds-combo-box.warning::part(input),
cds-textarea.warning::part(input),
cds-multi-select.warning::part(input) {
outline: 2px solid var(--cds-support-warning,#ffc300)
}

Expand Down
42 changes: 34 additions & 8 deletions frontend/src/components/forms/AutoCompleteInputComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { CDSComboBox } from "@carbon/web-components";
import { useEventBus } from "@vueuse/core";
// Types
import type { BusinessSearchResult, CodeNameType } from "@/dto/CommonTypesDto";
import { isEmpty } from "@/dto/CommonTypesDto";
import { isEmpty, type ValidationMessageType } from "@/dto/CommonTypesDto";
//Define the input properties for this component
const props = withDefaults(defineProps<{
Expand Down Expand Up @@ -44,6 +44,8 @@ const error = ref<string | undefined>(props.errorMessage ?? "");
const revalidateBus = useEventBus<void>("revalidate-bus");
const warning = ref(false);
watch(
() => props.errorMessage,
() => setError(props.errorMessage),
Expand Down Expand Up @@ -123,9 +125,27 @@ watch([inputValue], () => {
emitValueChange(inputValue.value);
});
const setError = (errorMessage: string | undefined) => {
error.value = errorMessage;
emit("error", error.value);
/**
* Sets the error and emits an error event.
* @param errorObject - the error object or string
*/
const setError = (errorObject: string | ValidationMessageType | undefined) => {
const errorMessage = typeof errorObject === "object" ? errorObject.errorMsg : errorObject;
error.value = errorMessage || "";
warning.value = false;
if (typeof errorObject === "object") {
warning.value = errorObject.warning;
}
/*
The error should be emitted whenever it is found, instead of watching and emitting only when it
changes.
Because the empty event is always emitted, even when it remains the same payload, and then we
rely on empty(false) to consider a value "valid". In turn we need to emit a new error event after
an empty one to allow subscribers to know in case the field still has the same error.
*/
emit('error', error.value);
}
//We call all the validations
Expand All @@ -138,7 +158,10 @@ const validateInput = (newValue: string) => {
if (errorMessage) return true;
return false;
})
.shift() ?? props.errorMessage,
.reduce(
(acc, errorMessage) => acc || errorMessage,
props.errorMessage,
)
);
}
};
Expand Down Expand Up @@ -221,6 +244,7 @@ const safeHelperText = computed(() => props.tip || " ");
<cds-combo-box
ref="cdsComboBoxRef"
:id="id"
:class="warning ? 'warning' : ''"
:autocomplete="autocomplete"
:title-text="label"
:aria-label="label"
Expand All @@ -231,9 +255,11 @@ const safeHelperText = computed(() => props.tip || " ");
:label="placeholder"
:value="inputValue"
filterable
:invalid="error ? true : false"
:invalid="!warning && error ? true : false"
:aria-invalid="ariaInvalidString"
:invalid-text="error"
:invalid-text="!warning && error"
:warn="warning"
:warn-text="warning && error"
@cds-combo-box-selected="selectAutocompleteItem"
v-on:input="onTyping"
@focus="isFocused = true"
Expand All @@ -246,7 +272,7 @@ const safeHelperText = computed(() => props.tip || " ");
:data-focus="id"
:data-scroll="id"
:data-id="'input-' + id"
v-shadow="3"
v-shadow="4"
>
<cds-combo-box-item
v-for="item in inputList"
Expand Down
47 changes: 39 additions & 8 deletions frontend/src/components/forms/DropdownInputComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { CDSComboBox } from "@carbon/web-components";
import { useEventBus } from "@vueuse/core";
// Types
import type { CodeNameType } from "@/dto/CommonTypesDto";
import { isEmpty } from "@/dto/CommonTypesDto";
import { isEmpty, type ValidationMessageType } from "@/dto/CommonTypesDto";
//Define the input properties for this component
const props = defineProps<{
Expand Down Expand Up @@ -37,6 +37,8 @@ const error = ref<string | undefined>(props.errorMessage ?? "");
const revalidateBus = useEventBus<void>("revalidate-bus");
const warning = ref(false);
//We set it as a separated ref due to props not being updatable
const selectedValue = ref(props.initialValue);
// This is to make the input list contains the selected value to show when component render
Expand All @@ -59,6 +61,30 @@ const emitValueChange = (newValue: string): void => {
emit("empty", isEmpty(newValue));
};
/**
* Sets the error and emits an error event.
* @param errorObject - the error object or string
*/
const setError = (errorObject: string | ValidationMessageType | undefined) => {
const errorMessage = typeof errorObject === "object" ? errorObject.errorMsg : errorObject;
error.value = errorMessage || "";
warning.value = false;
if (typeof errorObject === "object") {
warning.value = errorObject.warning;
}
/*
The error should be emitted whenever it is found, instead of watching and emitting only when it
changes.
Because the empty event is always emitted, even when it remains the same payload, and then we
rely on empty(false) to consider a value "valid". In turn we need to emit a new error event after
an empty one to allow subscribers to know in case the field still has the same error.
*/
emit('error', error.value);
}
/**
* Performs all validations and returns the first error message.
* If there's no error from the validations, returns props.errorMessage.
Expand All @@ -75,14 +101,17 @@ const validatePurely = (newValue: string): string | undefined => {
if (errorMessage) return true;
return false;
})
.shift() ?? props.errorMessage
.reduce(
(acc, errorMessage) => acc || errorMessage,
props.errorMessage
)
);
}
}
const validateInput = (newValue: any) => {
if (props.validations) {
error.value = validatePurely(newValue);
setError(validatePurely(newValue));
}
};
Expand Down Expand Up @@ -133,10 +162,9 @@ watch([selectedValue], () => {
watch(inputList, () => (selectedValue.value = props.initialValue));
//We watch for error changes to emit events
watch(error, () => emit("error", error.value));
watch(
() => props.errorMessage,
() => (error.value = props.errorMessage)
() => setError(props.errorMessage)
);
watch(
() => props.initialValue,
Expand Down Expand Up @@ -203,16 +231,19 @@ const safeHelperText = computed(() => props.tip || " ");
:autocomplete="autocomplete"
:title-text="label"
:aria-label="label"
:class="warning ? 'warning' : ''"
:clear-selection-label="`Clear ${label}`"
:required="required"
:data-required-label="requiredLabel"
filterable
:helper-text="safeHelperText"
:label="placeholder"
:value="selectedValue"
:invalid="error ? true : false"
:invalid="!warning && error ? true : false"
:aria-invalid="ariaInvalidString"
:invalidText="error"
:invalid-text="!warning && error"
:warn="warning"
:warn-text="warning && error"
@cds-combo-box-selected="selectItem"
@focus="isFocused = true"
@blur="
Expand All @@ -223,7 +254,7 @@ const safeHelperText = computed(() => props.tip || " ");
"
:data-focus="id"
:data-scroll="id"
v-shadow="3"
v-shadow="4"
>
<cds-combo-box-item
v-for="option in inputList"
Expand Down
44 changes: 38 additions & 6 deletions frontend/src/components/forms/MultiselectInputComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { CDSMultiSelect } from "@carbon/web-components";
// Composables
import { useEventBus } from "@vueuse/core";
// Types
import type { CodeNameType } from "@/dto/CommonTypesDto";
import type { CodeNameType, ValidationMessageType } from "@/dto/CommonTypesDto";
//Define the input properties for this component
const props = defineProps<{
Expand Down Expand Up @@ -36,6 +36,8 @@ const error = ref<string | undefined>(props.errorMessage ?? "");
const revalidateBus = useEventBus<void>("revalidate-bus");
const warning = ref(false);
//We set it as a separated ref due to props not being updatable
const selectedValue = ref(props.initialValue);
// This is to make the input list contains the selected value to show when component render
Expand All @@ -51,6 +53,29 @@ emit("empty", props.selectedValues ? props.selectedValues.length === 0 : true);
//Controls the selected values
const items = ref<string[]>([]);
/**
* Sets the error and emits an error event.
* @param errorObject - the error object or string
*/
const setError = (errorObject: string | ValidationMessageType | undefined) => {
const errorMessage = typeof errorObject === "object" ? errorObject.errorMsg : errorObject;
error.value = errorMessage || "";
warning.value = false;
if (typeof errorObject === "object") {
warning.value = errorObject.warning;
}
/*
The error should be emitted whenever it is found, instead of watching and emitting only when it
changes.
Because the empty event is always emitted, even when it remains the same payload, and then we
rely on empty(false) to consider a value "valid". In turn we need to emit a new error event after
an empty one to allow subscribers to know in case the field still has the same error.
*/
emit('error', error.value);
}
//We call all the validations
const validateInput = (newValue: any) => {
if (props.validations && props.validations.length > 0) {
Expand All @@ -62,9 +87,12 @@ const validateInput = (newValue: any) => {
props.validations
.map((validation) => validation(value))
.filter(hasError)
.shift() ?? props.errorMessage;
.reduce(
(acc, errorMessage) => acc || errorMessage,
props.errorMessage
);
error.value = validate(items.value);
setError(validate(items.value));
}
};
Expand Down Expand Up @@ -108,7 +136,7 @@ watch([selectedValue], () => validateInput(selectedValue.value));
watch(error, () => emit("error", error.value));
watch(
() => props.errorMessage,
() => (error.value = props.errorMessage)
() => setError(props.errorMessage)
);
revalidateBus.on(() => validateInput(selectedValue.value));
Expand Down Expand Up @@ -162,14 +190,17 @@ watch(
:id="id"
:value="selectedValue"
:label="selectedValue"
:class="warning ? 'warning' : ''"
:title-text="label"
:aria-label="label"
:required="required"
:data-required-label="requiredLabel"
:helper-text="tip"
:invalid="error ? true : false"
:invalid="!warning && error ? true : false"
:aria-invalid="ariaInvalidString"
:invalid-text="error"
:invalid-text="!warning && error"
:warn="warning"
:warn-text="warning && error"
filterable
@cds-multi-select-selected="selectItems"
@focus="isFocused = true"
Expand All @@ -181,6 +212,7 @@ watch(
"
:data-focus="id"
:data-scroll="id"
v-shadow="4"
>
<cds-multi-select-item
v-for="option in inputList"
Expand Down
29 changes: 20 additions & 9 deletions frontend/src/components/forms/TextareaInputComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "@carbon/web-components/es/components/textarea/index";
// Composables
import { useEventBus } from "@vueuse/core";
// Types
import { isEmpty } from "@/dto/CommonTypesDto";
import { isEmpty, type ValidationMessageType } from "@/dto/CommonTypesDto";
//Define the input properties for this component
const props = withDefaults(
Expand Down Expand Up @@ -39,12 +39,20 @@ const error = ref<string | undefined>(props.errorMessage ?? "");
const revalidateBus = useEventBus<void>("revalidate-bus");
const warning = ref(false);
/**
* Sets the error and emits an error event.
* @param errorMessage - the error message
* @param errorObject - the error object or string
*/
const setError = (errorMessage: string | undefined) => {
error.value = errorMessage;
const setError = (errorObject: string | ValidationMessageType | undefined) => {
const errorMessage = typeof errorObject === "object" ? errorObject.errorMsg : errorObject;
error.value = errorMessage || "";
warning.value = false;
if (typeof errorObject === "object") {
warning.value = errorObject.warning;
}
/*
The error should be emitted whenever it is found, instead of watching and emitting only when it
Expand All @@ -53,8 +61,8 @@ const setError = (errorMessage: string | undefined) => {
rely on empty(false) to consider a value "valid". In turn we need to emit a new error event after
an empty one to allow subscribers to know in case the field still has the same error.
*/
emit("error", error.value);
};
emit('error', error.value);
}
watch(
() => props.errorMessage,
Expand Down Expand Up @@ -130,6 +138,7 @@ const ariaInvalidString = computed(() => (error.value ? "true" : "false"));
v-if="enabled"
:id="id"
:rows="rows"
:class="warning ? 'warning' : ''"
:enable-counter="enableCounter"
:max-count="maxCount"
:required="required"
Expand All @@ -140,9 +149,11 @@ const ariaInvalidString = computed(() => (error.value ? "true" : "false"));
:value="selectedValue"
:helper-text="tip"
:disabled="!enabled"
:invalid="error ? true : false"
:invalid="!warning && error ? true : false"
:aria-invalid="ariaInvalidString"
:invalid-text="error"
:invalid-text="!warning && error"
:warn="warning"
:warn-text="warning && error"
@focus="isFocused = true"
@blur="
(event: any) => {
Expand All @@ -154,7 +165,7 @@ const ariaInvalidString = computed(() => (error.value ? "true" : "false"));
:data-focus="id"
:data-scroll="id"
:data-id="'input-' + id"
v-shadow="3"
v-shadow="4"
>
<slot></slot>
</cds-textarea>
Expand Down
Loading

0 comments on commit 89e6a63

Please sign in to comment.