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

feat: adding province load #343

Merged
merged 9 commits into from
Feb 16, 2023
34 changes: 23 additions & 11 deletions frontend/src/common/FormAutocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,30 @@
</b-form-input>
<datalist :id="fieldProps.dataListId">
<option
v-for="entry in searchData"
:key="entry.code"
:value="entry.name">
{{entry.name}}
v-for="entry in searchData"
:value="entry.value">
{{entry.text}}
</option>
</datalist>
</FormFieldTemplate>
</template>

<script setup lang="ts">
import { computed, reactive, watch, ref } from "vue";
import { computed, watch, ref } from "vue";
import type { PropType } from "vue";
import FormFieldTemplate from "./FormFieldTemplate.vue";
import type { FormFieldAutoCompleteTemplateType } from "../core/FormType";
import { useFetchTo } from "../services/forestClient.service";
import FormFieldTemplate from "@/common/FormFieldTemplate.vue";
import type { FormFieldAutoCompleteTemplateType } from "@/core/FormType";

//This is the event bus used to update the data and do the autocomplete
import EventBus from "@/services/EventBus";

const emit = defineEmits(["updateValue"]);

const props = defineProps({
// form field template props (optional): label, required, tooltip, note, id, errorMsg
fieldProps: {
type: Object as PropType<FormFieldAutoCompleteTemplateType>,
default: { id: "form-input",dataListId: "form-input-datalist" },
default: { id: "form-input", dataListId: "form-input-datalist", minSizeSearch:3 },
},
value: { type: [String, Number], required: true },
disabled: { type: Boolean, default: false },
Expand All @@ -42,11 +43,22 @@ const computedValue = computed({
},
});

//The property associated to the datalist
let searchData = ref([]);

//We wire the response of the event to the update of the datalist
EventBus.addEventListener(props.fieldProps.dataListId!, (ev: any) => {
//We update the searchData with the event data
//The data should be previously converted
searchData.value = ev.data;
});

//We watch the text data being changed
watch(computedValue,(curr,_) =>{
if(curr.toString().length >= 3){
useFetchTo(`/api/orgbook/name/${curr}`,searchData,{method: 'get'});
//When the text data is bigger than the expected size
if(curr.toString().length >= props.fieldProps.minSizeSearch!){
//We emmit an event to notify that the data changed
EventBus.emit(props.fieldProps.id,curr);
}
});
</script>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/common/FormSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
FormFieldTemplateType,
FormSelectOptionType,
} from "../core/FormType";
import EventBus from "@/services/EventBus";

const props = defineProps({
// form field template props (optional): label, required, tooltip, note, id, errorMsg
Expand All @@ -45,6 +46,7 @@ const computedValue = computed({
},
set(newValue: CommonObjectType | string) {
emit("updateValue", newValue, props.fieldProps.modelName);
EventBus.emit(props.fieldProps.id,newValue);
},
});
</script>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/core/FormType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface FormFieldAutoCompleteTemplateType {
note?: string;
tooltip?: string;
errorMsg?: string;
minSizeSearch?: number;
}

export interface FormSelectOptionType {
Expand Down
33 changes: 22 additions & 11 deletions frontend/src/pages/applynewclient/formsections/FormSections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,24 @@
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { computed } from "vue";
import _ from "lodash";
import FormSectionTemplate from "./FormSectionTemplate.vue";
import { businessTypeSectionSchema } from "../formsectionschemas/BusinessTypeSectionSchema";
import { informationSectionSchema } from "../formsectionschemas/InformationSectionSchema";
import { locationSectionSchema } from "../formsectionschemas/LocationSectionSchema";
import { formData } from "../../../store/newclientform/FormData";
import { useFetch, useFetchTo } from "../../../services/forestClient.service";

const conversionFn = (code: any) => {return {value: code.code, text: code.name}};
import FormSectionTemplate from "@/pages/applynewclient/formsections/FormSectionTemplate.vue";
import { businessTypeSectionSchema } from "@/pages/applynewclient/formsectionschemas/BusinessTypeSectionSchema";
import { informationSectionSchema } from "@/pages/applynewclient/formsectionschemas/InformationSectionSchema";
import { locationSectionSchema } from "@/pages/applynewclient/formsectionschemas/LocationSectionSchema";
import { formData } from "@/store/newclientform/FormData";
import { useFetch } from "@/services/forestClient.service";
import { useBusinessNameIdAutoComplete, useCountryIdAutoComplete, conversionFn } from "@/services/FetchService.ts";


//We call it here to enable autocomplete
useBusinessNameIdAutoComplete();
//We will update the provinces based on the province update
const { data: provinceCodes } = useCountryIdAutoComplete();

const { data: activeClientTypeCodes } = useFetch('/api/clients/activeClientTypeCodes', { method:'get', initialData:[] });
const { data: countryCodes } = useFetch('/api/clients/activeCountryCodes?page=0&size=250', { method:'get', initialData:[] }); //TODO: Change to autocomplete
const { data: countryCodes } = useFetch('/api/clients/activeCountryCodes?page=0&size=250', { method:'get', initialData:[] });

const computedBusinessTypeSectionSchema = computed(() => {
const schemaCopy = businessTypeSectionSchema
Expand Down Expand Up @@ -77,10 +83,16 @@ const computedLocationSectionSchema = computed(() => {

Object.keys(subFields).forEach((subKey) => {
const subfields = subFields[subKey];

const newsubfields = subfields.map((p) =>
p.fieldProps.modelName == "country"
? { ...p, options: countryCodes.value.map(conversionFn) }
: p
)
.map((p) =>
p.fieldProps.modelName == "province"
? { ...p, options: provinceCodes.value.map(conversionFn) }
: p
);
subFields[subKey] = newsubfields;
});
Expand All @@ -100,7 +112,6 @@ const computedLocationSectionSchema = computed(() => {

<script lang="ts">
import { defineComponent } from "vue";
import { FormSelectOptionType } from "../../../core/FormType";
export default defineComponent({
name: "ApplyNewClientPage",
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const informationSectionSchema: {
dataListId: "businessNameListId",
modelName: "businessName",
required: true,
note: "The name must be the same as it is in BC Registries",
note: "The name must be the same as it is in BC Registries"
},
type: "autocomplete",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export const locationSectionSchema: FormSectionSchemaType = {
modelName: "province",
required: true,
},
type: "input",
type: "select",
options: [],
},
{
fieldProps: {
Expand Down Expand Up @@ -105,7 +106,7 @@ export const locationSectionSchema: FormSectionSchemaType = {
},
type: "select",
options: [],
},
},
{
fieldProps: {
label: "Daytime phone number",
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/services/EventBus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export class EventBusEvent extends Event {
public data: any;

constructor({ type, data }: { type: string; data: any }) {
super(type);
this.data = data;
}
}

class EventBus extends EventTarget {
private static _instance: EventBus;

public static getInstance(): EventBus {
if (!this._instance) this._instance = new EventBus();
return this._instance;
}

public emit(type: string, data?: any): void {
this.dispatchEvent(new EventBusEvent({ type, data }));
}
}

export default EventBus.getInstance();
43 changes: 43 additions & 0 deletions frontend/src/services/FetchService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* This file will have control over fetching of everything
*/
import { ref, watch } from "vue";
import { useFetchTo } from "@/services/forestClient.service";
import EventBus, { EventBusEvent } from "@/services/EventBus";

export const conversionFn = (code: any) => { return { value: code.code, text: code.name } };

/**
* Autocomplete function for the business name
*/
export const useBusinessNameIdAutoComplete = () => {
//To control data update back to the list
const data = ref([]);
//We will listen to changes on the businessNameId text field and do the fetch
EventBus.addEventListener("businessNameId", (ev: any) => {
useFetchTo(`/api/orgbook/name/${ev.data}`, data, { method: "get" });
});
//We watch for changes on the data to emit back to the datalist
watch(data, (dataFetched, _) => {
EventBus.emit("businessNameListId", data.value.map((code: any) => {
return { value: code.name, text: code.name }
}));
});
};

/**
* Monitor the countryId change to load the provinces
* @returns a list of provinces/states
*/
export const useCountryIdAutoComplete = () => {
//To control data update back to the list
const data = ref([]);
//We will listen to changes on the country dropdown and do the fetch
EventBus.addEventListener("countryId", (ev: any) => {
//We then fetch the provinces for that country into the data ref
useFetchTo(`/api/clients/activeCountryCodes/${ev.data}?page=0&size=250`, data, { method: 'get' });
});

//We return the data
return { data };
};