@servicetitan/onboarding-ui 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/company-profile/components/company-profile-form.d.ts +5 -0
  2. package/dist/company-profile/components/company-profile-form.d.ts.map +1 -0
  3. package/dist/company-profile/components/company-profile-form.js +42 -0
  4. package/dist/company-profile/components/company-profile-form.js.map +1 -0
  5. package/dist/company-profile/components/company-profile.module.less +7 -0
  6. package/dist/company-profile/components/country-dropdown-input.d.ts +9 -0
  7. package/dist/company-profile/components/country-dropdown-input.d.ts.map +1 -0
  8. package/dist/company-profile/components/country-dropdown-input.js +13 -0
  9. package/dist/company-profile/components/country-dropdown-input.js.map +1 -0
  10. package/dist/company-profile/components/state-and-province-dropdown-input.d.ts +14 -0
  11. package/dist/company-profile/components/state-and-province-dropdown-input.d.ts.map +1 -0
  12. package/dist/company-profile/components/state-and-province-dropdown-input.js +50 -0
  13. package/dist/company-profile/components/state-and-province-dropdown-input.js.map +1 -0
  14. package/dist/company-profile/index.d.ts +7 -0
  15. package/dist/company-profile/index.d.ts.map +1 -0
  16. package/dist/company-profile/index.js +19 -0
  17. package/dist/company-profile/index.js.map +1 -0
  18. package/dist/company-profile/stores/__mocks__/company-profile-form-mock-data.d.ts +5 -0
  19. package/dist/company-profile/stores/__mocks__/company-profile-form-mock-data.d.ts.map +1 -0
  20. package/dist/company-profile/stores/__mocks__/company-profile-form-mock-data.js +32 -0
  21. package/dist/company-profile/stores/__mocks__/company-profile-form-mock-data.js.map +1 -0
  22. package/dist/company-profile/stores/company-profile-form.store.d.ts +65 -0
  23. package/dist/company-profile/stores/company-profile-form.store.d.ts.map +1 -0
  24. package/dist/company-profile/stores/company-profile-form.store.js +200 -0
  25. package/dist/company-profile/stores/company-profile-form.store.js.map +1 -0
  26. package/dist/company-profile/utils/validators.d.ts +2 -0
  27. package/dist/company-profile/utils/validators.d.ts.map +1 -0
  28. package/dist/company-profile/utils/validators.js +14 -0
  29. package/dist/company-profile/utils/validators.js.map +1 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +14 -0
  33. package/dist/index.js.map +1 -0
  34. package/package.json +64 -0
  35. package/src/company-profile/components/company-profile-form.tsx +140 -0
  36. package/src/company-profile/components/company-profile.module.less +7 -0
  37. package/src/company-profile/components/company-profile.module.less.d.ts +4 -0
  38. package/src/company-profile/components/country-dropdown-input.tsx +28 -0
  39. package/src/company-profile/components/state-and-province-dropdown-input.tsx +74 -0
  40. package/src/company-profile/index.ts +6 -0
  41. package/src/company-profile/stores/__mocks__/company-profile-form-mock-data.ts +32 -0
  42. package/src/company-profile/stores/__tests__/company-profile-form.store.test.ts +41 -0
  43. package/src/company-profile/stores/company-profile-form.store.ts +151 -0
  44. package/src/company-profile/utils/validators.ts +11 -0
  45. package/src/index.ts +1 -0
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ export declare const CompanyProfileForm: (props: {
3
+ className?: string;
4
+ }) => JSX.Element;
5
+ //# sourceMappingURL=company-profile-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form.d.ts","sourceRoot":"","sources":["../../../src/company-profile/components/company-profile-form.tsx"],"names":[],"mappings":";AAUA,eAAO,MAAM,kBAAkB,UAAoB;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,gBAiIvE,CAAC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CompanyProfileForm = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const design_system_1 = require("@servicetitan/design-system");
9
+ const classnames_1 = __importDefault(require("classnames"));
10
+ const country_dropdown_input_1 = require("./country-dropdown-input");
11
+ const mobx_react_1 = require("mobx-react");
12
+ const react_ioc_1 = require("@servicetitan/react-ioc");
13
+ const state_and_province_dropdown_input_1 = require("./state-and-province-dropdown-input");
14
+ const company_profile_form_store_1 = require("../stores/company-profile-form.store");
15
+ const form_1 = require("@servicetitan/form");
16
+ exports.CompanyProfileForm = mobx_react_1.observer((props) => {
17
+ const [store] = react_ioc_1.useDependencies(company_profile_form_store_1.CompanyProfileFormStore);
18
+ const { form, showFormError, zipCodeMask, einOrBnMask, einOrBnInputProps } = store;
19
+ const zipCodeOnChangeHandler = (e) => {
20
+ form.$.companyZipCode.onChangeHandler(e, {
21
+ value: e.target.value,
22
+ });
23
+ };
24
+ const einOrBnOnChangeHandler = (e) => {
25
+ form.$.einOrBn.onChangeHandler(e, {
26
+ value: (e.target.value || '').replace(/[^0-9.]/g, ''),
27
+ });
28
+ };
29
+ const phoneOnChangeHandler = (e) => {
30
+ form.$.adminPhone.onChangeHandler(e, { value: e.target.value });
31
+ };
32
+ const countryOnChangeHandler = (event, data) => {
33
+ if (form.$.companyCountry.$ && data.value !== form.$.companyCountry.$) {
34
+ form.$.companyStateCode.onChange('');
35
+ }
36
+ form.$.companyCountry.onChangeHandler(event, data);
37
+ };
38
+ const { companyName, companyStreetAddress, companyCity, companyCountry, companyStateCode, companyZipCode, adminPhone, einOrBn, } = store.form.$;
39
+ const zipCodeHasError = companyZipCode.hasError;
40
+ return (jsx_runtime_1.jsxs(design_system_1.Form, Object.assign({ size: "tiny", className: classnames_1.default(props.className, 'ta-left', 'p-x-6') }, { children: [jsx_runtime_1.jsx(design_system_1.Form.Input, { label: "Company Name", placeholder: "Company Name", value: companyName.value, onChange: companyName.onChangeHandler, error: (companyName.dirty || showFormError) && companyName.hasError }, void 0), jsx_runtime_1.jsx(design_system_1.Form.Input, { label: "Street Address", placeholder: "Street Address", value: companyStreetAddress.value, onChange: companyStreetAddress.onChangeHandler, error: (companyStreetAddress.dirty || showFormError) && companyStreetAddress.hasError }, void 0), jsx_runtime_1.jsxs(design_system_1.Form.Group, Object.assign({ width: "equal" }, { children: [jsx_runtime_1.jsx(design_system_1.Form.Input, { fluid: true, label: "City", placeholder: "City", className: "p-r-0", width: "6", value: companyCity.value, onChange: companyCity.onChangeHandler, error: (companyCity.dirty || showFormError) && companyCity.hasError }, void 0), jsx_runtime_1.jsx(state_and_province_dropdown_input_1.StateAndProvinceDropdownInput, { width: "6", countryCode: companyCountry.value || 'USA', fieldState: companyStateCode, error: (companyStateCode.dirty || showFormError) && companyStateCode.hasError, countryAndRegionData: store.countryAndRegionData, regionNameToCodeMap: store.regionToCodeMap }, void 0)] }), void 0), jsx_runtime_1.jsxs(design_system_1.Form.Group, Object.assign({ width: "equal" }, { children: [jsx_runtime_1.jsx(form_1.MaskedInput, { fluid: true, label: "ZIP Code", placeholder: "ZIP Code", value: companyZipCode.value, onChange: zipCodeOnChangeHandler, mask: zipCodeMask, className: "p-r-0", maskChar: " ", error: (companyZipCode.dirty || showFormError) && zipCodeHasError, width: 6 }, void 0), jsx_runtime_1.jsx(country_dropdown_input_1.CountryDropdownInput, { width: "6", value: companyCountry.value, onChange: countryOnChangeHandler, error: (companyCountry.dirty || showFormError) && companyCountry.hasError, options: store.countries.map(x => ({ key: x, value: x, text: x })) }, void 0)] }), void 0), jsx_runtime_1.jsxs(design_system_1.Form.Group, Object.assign({ width: "equal" }, { children: [jsx_runtime_1.jsx(form_1.MaskedInput, { fluid: true, label: "Phone Number", placeholder: "Phone Number", value: adminPhone.value, onChange: phoneOnChangeHandler, error: (adminPhone.dirty || showFormError) && adminPhone.hasError, mask: store.phoneMask, width: 6 }, void 0), jsx_runtime_1.jsx(form_1.MaskedInput, { fluid: true, label: einOrBnInputProps.label, placeholder: einOrBnInputProps.placeholder, value: einOrBn.value, onChange: einOrBnOnChangeHandler, mask: einOrBnMask, className: "p-r-0", maskChar: " ", error: (einOrBn.dirty || showFormError) && einOrBn.hasError, width: 6 }, void 0)] }), void 0)] }), void 0));
41
+ });
42
+ //# sourceMappingURL=company-profile-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form.js","sourceRoot":"","sources":["../../../src/company-profile/components/company-profile-form.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ .company-profile-container {
2
+ max-width: 650px !important;
3
+ }
4
+
5
+ .company-profile-form {
6
+ margin-bottom: 9px;
7
+ }
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" />
2
+ import { FormDropdownProps, SemanticWIDTHS } from '@servicetitan/design-system';
3
+ import { Option } from '@servicetitan/form';
4
+ export interface ICountryDropdownInput extends FormDropdownProps {
5
+ options: Option<string>[];
6
+ width?: SemanticWIDTHS;
7
+ }
8
+ export declare const CountryDropdownInput: (props: ICountryDropdownInput) => JSX.Element;
9
+ //# sourceMappingURL=country-dropdown-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"country-dropdown-input.d.ts","sourceRoot":"","sources":["../../../src/company-profile/components/country-dropdown-input.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAQ,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAEtF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC5D,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,eAAO,MAAM,oBAAoB,UAAoB,qBAAqB,gBAiBxE,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CountryDropdownInput = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const design_system_1 = require("@servicetitan/design-system");
6
+ const mobx_react_1 = require("mobx-react");
7
+ exports.CountryDropdownInput = mobx_react_1.observer((props) => {
8
+ var _a, _b;
9
+ const value = props.value && props.value.toString().toLowerCase();
10
+ const country = value && (value === 'canada' || value === 'ca' ? 'Canada' : 'USA');
11
+ return (jsx_runtime_1.jsx(design_system_1.Form.Select, { fluid: true, search: true, width: (_a = props.width) !== null && _a !== void 0 ? _a : '12', label: "Country", placeholder: (_b = props.placeholder) !== null && _b !== void 0 ? _b : 'Country', className: props.className, value: country, onChange: props.onChange, options: props.options, error: props.error }, void 0));
12
+ });
13
+ //# sourceMappingURL=country-dropdown-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"country-dropdown-input.js","sourceRoot":"","sources":["../../../src/company-profile/components/country-dropdown-input.tsx"],"names":[],"mappings":";;;;AACA,+DAAsF;AACtF,2CAAsC;AAQzB,QAAA,oBAAoB,GAAG,qBAAQ,CAAC,CAAC,KAA4B,EAAE,EAAE;;IAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAM,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC;IACnE,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,OAAO,CACH,kBAAC,oBAAI,CAAC,MAAM,IACR,KAAK,QACL,MAAM,QACN,KAAK,EAAE,MAAA,KAAK,CAAC,KAAK,mCAAI,IAAI,EAC1B,KAAK,EAAC,SAAS,EACf,WAAW,EAAE,MAAA,KAAK,CAAC,WAAW,mCAAI,SAAS,EAC3C,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,KAAK,EAAE,KAAK,CAAC,KAAK,WACpB,CACL,CAAC;AACN,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import { FormDropdownProps, SemanticWIDTHS } from '@servicetitan/design-system';
3
+ import { DropdownFieldState } from '@servicetitan/form';
4
+ import { CountryWithRegions } from '../stores/company-profile-form.store';
5
+ interface StateAndProvinceDropdownInputProps extends FormDropdownProps {
6
+ countryCode: string;
7
+ fieldState: DropdownFieldState<string>;
8
+ countryAndRegionData: CountryWithRegions[];
9
+ regionNameToCodeMap: Map<string, string>;
10
+ width?: SemanticWIDTHS;
11
+ }
12
+ export declare const StateAndProvinceDropdownInput: (props: StateAndProvinceDropdownInputProps) => JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=state-and-province-dropdown-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-and-province-dropdown-input.d.ts","sourceRoot":"","sources":["../../../src/company-profile/components/state-and-province-dropdown-input.tsx"],"names":[],"mappings":";AACA,OAAO,EAAQ,iBAAiB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAkB,MAAM,sCAAsC,CAAC;AAE1F,UAAU,kCAAmC,SAAQ,iBAAiB;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACvC,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;IAC3C,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;CAC1B;AAKD,eAAO,MAAM,6BAA6B,UAC9B,kCAAkC,gBAuD7C,CAAC"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StateAndProvinceDropdownInput = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const design_system_1 = require("@servicetitan/design-system");
10
+ const mobx_react_1 = require("mobx-react");
11
+ const toTitleCase = (str) => str.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
12
+ exports.StateAndProvinceDropdownInput = mobx_react_1.observer((props) => {
13
+ var _a, _b;
14
+ const { value, onChange, onChangeHandler } = props.fieldState;
15
+ react_1.default.useEffect(() => {
16
+ var _a;
17
+ /*
18
+ * requirement: convert any incoming state value that is a full state/province name
19
+ * to it's respective state code (e.g. 'Alabama' => 'AL')
20
+ * The incoming value may not have proper casing
21
+ * (salesforce data input through text input field not dropdown),
22
+ * so convert to proper casing to find value in map
23
+ * https://servicetitan.atlassian.net/browse/OX-948
24
+ */
25
+ if (value && value.length > 2) {
26
+ onChange((_a = props.regionNameToCodeMap.get(toTitleCase(value))) !== null && _a !== void 0 ? _a : ' ');
27
+ }
28
+ }, [onChange, props.regionNameToCodeMap, value]);
29
+ let americanRegionalData;
30
+ let canadianRegionalData;
31
+ props.countryAndRegionData.forEach((countryOption) => {
32
+ const data = countryOption.Regions.map((option) => ({
33
+ key: option.Code,
34
+ value: option.Code,
35
+ text: option.Name,
36
+ }));
37
+ if (countryOption.Country === 'US') {
38
+ americanRegionalData = data;
39
+ }
40
+ if (countryOption.Country === 'CA') {
41
+ canadianRegionalData = data;
42
+ }
43
+ });
44
+ const regionType = props.countryCode.toLowerCase() === 'canada' || props.countryCode.toLowerCase() === 'ca'
45
+ ? 'Province'
46
+ : 'State';
47
+ const options = regionType === 'Province' ? canadianRegionalData : americanRegionalData;
48
+ return (jsx_runtime_1.jsx(design_system_1.Form.Select, { search: true, fluid: true, width: (_a = props.width) !== null && _a !== void 0 ? _a : '12', label: regionType, placeholder: (_b = props.placeholder) !== null && _b !== void 0 ? _b : regionType, className: props.className, value: value, onChange: onChangeHandler, options: options, error: props.error }, void 0));
49
+ });
50
+ //# sourceMappingURL=state-and-province-dropdown-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-and-province-dropdown-input.js","sourceRoot":"","sources":["../../../src/company-profile/components/state-and-province-dropdown-input.tsx"],"names":[],"mappings":";;;;;;;AAAA,kDAA0B;AAC1B,+DAAsF;AACtF,2CAAsC;AAYtC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE,CAChC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAE/E,QAAA,6BAA6B,GAAG,qBAAQ,CACjD,CAAC,KAAyC,EAAE,EAAE;;IAC1C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;IAE9D,eAAK,CAAC,SAAS,CAAC,GAAG,EAAE;;QACjB;;;;;;;WAOG;QACH,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,QAAQ,CAAC,MAAA,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,mCAAI,GAAG,CAAC,CAAC;SACtE;IACL,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjD,IAAI,oBAAoB,CAAC;IACzB,IAAI,oBAAoB,CAAC;IAEzB,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,aAAiC,EAAE,EAAE;QACrE,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAsB,EAAE,EAAE,CAAC,CAAC;YAChE,GAAG,EAAE,MAAM,CAAC,IAAI;YAChB,KAAK,EAAE,MAAM,CAAC,IAAI;YAClB,IAAI,EAAE,MAAM,CAAC,IAAI;SACpB,CAAC,CAAC,CAAC;QACJ,IAAI,aAAa,CAAC,OAAO,KAAK,IAAI,EAAE;YAChC,oBAAoB,GAAG,IAAI,CAAC;SAC/B;QACD,IAAI,aAAa,CAAC,OAAO,KAAK,IAAI,EAAE;YAChC,oBAAoB,GAAG,IAAI,CAAC;SAC/B;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GACZ,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI;QACpF,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,OAAO,CAAC;IAClB,MAAM,OAAO,GAAG,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAExF,OAAO,CACH,kBAAC,oBAAI,CAAC,MAAM,IACR,MAAM,QACN,KAAK,QACL,KAAK,EAAE,MAAA,KAAK,CAAC,KAAK,mCAAI,IAAI,EAC1B,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,MAAA,KAAK,CAAC,WAAW,mCAAI,UAAU,EAC5C,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,OAAQ,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,WACpB,CACL,CAAC;AACN,CAAC,CACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './components/company-profile-form';
2
+ export * from './components/country-dropdown-input';
3
+ export * from './components/state-and-province-dropdown-input';
4
+ export * from './stores/company-profile-form.store';
5
+ export * from './stores/__mocks__/company-profile-form-mock-data';
6
+ export * from './utils/validators';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/company-profile/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qCAAqC,CAAC;AACpD,cAAc,mDAAmD,CAAC;AAClE,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./components/company-profile-form"), exports);
14
+ __exportStar(require("./components/country-dropdown-input"), exports);
15
+ __exportStar(require("./components/state-and-province-dropdown-input"), exports);
16
+ __exportStar(require("./stores/company-profile-form.store"), exports);
17
+ __exportStar(require("./stores/__mocks__/company-profile-form-mock-data"), exports);
18
+ __exportStar(require("./utils/validators"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/company-profile/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oEAAkD;AAClD,sEAAoD;AACpD,iFAA+D;AAC/D,sEAAoD;AACpD,oFAAkE;AAClE,qDAAmC"}
@@ -0,0 +1,5 @@
1
+ import { ProfileModel } from '../company-profile-form.store';
2
+ export declare const CompanyProfileFormCorrect: ProfileModel;
3
+ export declare const CompanyProfileFormEmptyValues: ProfileModel;
4
+ export declare const CompanyProfileFormCanadian: ProfileModel;
5
+ //# sourceMappingURL=company-profile-form-mock-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form-mock-data.d.ts","sourceRoot":"","sources":["../../../../src/company-profile/stores/__mocks__/company-profile-form-mock-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,eAAO,MAAM,yBAAyB,EAAE,YASvC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,YAQ3C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,YAQxC,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompanyProfileFormCanadian = exports.CompanyProfileFormEmptyValues = exports.CompanyProfileFormCorrect = void 0;
4
+ exports.CompanyProfileFormCorrect = {
5
+ companyName: 'Wyatt Works',
6
+ adminPhone: '(310) 855-8585',
7
+ companyStreetAddress: '123 Main St.',
8
+ companyCountry: 'USA',
9
+ companyStateCode: 'CA',
10
+ companyCity: 'Glendale',
11
+ companyZipCode: '12345',
12
+ einOrBn: '',
13
+ };
14
+ exports.CompanyProfileFormEmptyValues = {
15
+ companyName: '',
16
+ adminPhone: '',
17
+ companyStreetAddress: '',
18
+ companyCountry: '',
19
+ companyStateCode: '',
20
+ companyCity: '',
21
+ companyZipCode: '',
22
+ };
23
+ exports.CompanyProfileFormCanadian = {
24
+ companyName: 'Wyatt Works',
25
+ adminPhone: '(310) 855-8585',
26
+ companyStreetAddress: '123 Main St.',
27
+ companyCountry: 'ca',
28
+ companyStateCode: 'CA',
29
+ companyCity: 'Glendale',
30
+ companyZipCode: '12345',
31
+ };
32
+ //# sourceMappingURL=company-profile-form-mock-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form-mock-data.js","sourceRoot":"","sources":["../../../../src/company-profile/stores/__mocks__/company-profile-form-mock-data.ts"],"names":[],"mappings":";;;AAEa,QAAA,yBAAyB,GAAiB;IACnD,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,gBAAgB;IAC5B,oBAAoB,EAAE,cAAc;IACpC,cAAc,EAAE,KAAK;IACrB,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,UAAU;IACvB,cAAc,EAAE,OAAO;IACvB,OAAO,EAAE,EAAE;CACd,CAAC;AAEW,QAAA,6BAA6B,GAAiB;IACvD,WAAW,EAAE,EAAE;IACf,UAAU,EAAE,EAAE;IACd,oBAAoB,EAAE,EAAE;IACxB,cAAc,EAAE,EAAE;IAClB,gBAAgB,EAAE,EAAE;IACpB,WAAW,EAAE,EAAE;IACf,cAAc,EAAE,EAAE;CACrB,CAAC;AAEW,QAAA,0BAA0B,GAAiB;IACpD,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,gBAAgB;IAC5B,oBAAoB,EAAE,cAAc;IACpC,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,UAAU;IACvB,cAAc,EAAE,OAAO;CAC1B,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { FieldState, FormState } from 'formstate';
2
+ import { InputFieldState, DropdownFieldState } from '@servicetitan/form';
3
+ export interface DropdownRegion {
4
+ Code: string;
5
+ Name: string;
6
+ }
7
+ export interface CountryWithRegions {
8
+ Country: string;
9
+ Regions: DropdownRegion[];
10
+ }
11
+ export interface ProfileModel {
12
+ companyName?: string | undefined;
13
+ adminPhone?: string | undefined;
14
+ companyStreetAddress?: string | undefined;
15
+ companyCountry?: string | undefined;
16
+ companyStateCode?: string | undefined;
17
+ companyCity?: string | undefined;
18
+ companyZipCode?: string | undefined;
19
+ einOrBn?: string | undefined;
20
+ }
21
+ export interface ICompanyProfileFormType {
22
+ [key: string]: FieldState<any>;
23
+ companyName: InputFieldState<string>;
24
+ adminPhone: InputFieldState<string>;
25
+ companyStreetAddress: InputFieldState<string>;
26
+ companyCountry: DropdownFieldState<string>;
27
+ companyStateCode: DropdownFieldState<string>;
28
+ companyCity: InputFieldState<string>;
29
+ companyZipCode: InputFieldState<string>;
30
+ einOrBn: InputFieldState<string>;
31
+ }
32
+ export interface ICompanyProfileFormStore {
33
+ showFormError: boolean;
34
+ isInitializing: boolean;
35
+ form: FormState<ICompanyProfileFormType>;
36
+ }
37
+ interface CompanyProfileFormOptions {
38
+ phonePattern: RegExp;
39
+ countries: string[];
40
+ countryAndRegionData: CountryWithRegions[];
41
+ phoneMask: string;
42
+ regionToCodeMap: Map<string, string>;
43
+ }
44
+ export declare class CompanyProfileFormStore implements ICompanyProfileFormStore {
45
+ showFormError: boolean;
46
+ isInitializing: boolean;
47
+ countries: string[];
48
+ countryAndRegionData: CountryWithRegions[];
49
+ phoneMask: string;
50
+ regionToCodeMap: Map<string, string>;
51
+ form: FormState<ICompanyProfileFormType>;
52
+ constructor();
53
+ setFormErrorCheck: (value: boolean) => void;
54
+ isCanada: (country: string) => boolean;
55
+ get zipCodeMask(): "99999" | "*** ***";
56
+ get einOrBnMask(): "999999999" | "99-9999999";
57
+ get einOrBnInputProps(): {
58
+ label: string;
59
+ placeholder: string;
60
+ };
61
+ initForm: (formData: ProfileModel, options: CompanyProfileFormOptions) => void;
62
+ commitForm: () => void;
63
+ }
64
+ export {};
65
+ //# sourceMappingURL=company-profile-form.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form.store.d.ts","sourceRoot":"","sources":["../../../src/company-profile/stores/company-profile-form.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACH,eAAe,EACf,kBAAkB,EAGrB,MAAM,oBAAoB,CAAC;AAO5B,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAOD,MAAM,WAAW,uBAAuB;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,WAAW,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,oBAAoB,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9C,cAAc,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3C,gBAAgB,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC7C,WAAW,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,IAAI,EAAE,SAAS,CAAC,uBAAuB,CAAC,CAAC;CAC5C;AAED,UAAU,yBAAyB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,qBACa,uBAAwB,YAAW,wBAAwB;IACxD,aAAa,UAAS;IACtB,cAAc,UAAS;IACvB,SAAS,EAAE,MAAM,EAAE,CAAM;IACzB,oBAAoB,EAAE,kBAAkB,EAAE,CAAM;IAChD,SAAS,SAAM;IACf,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IAE7D,IAAI,EAAE,SAAS,CAAC,uBAAuB,CAAC,CASrC;;IAsBH,iBAAiB,UAAW,OAAO,UAEjC;IAEF,QAAQ,YAAa,MAAM,aAGzB;IAEF,IACI,WAAW,wBAEd;IAED,IACI,WAAW,+BAEd;IAED,IACI,iBAAiB;;;MAUpB;IAGD,QAAQ,aAAc,YAAY,WAAW,yBAAyB,UAQpE;IAGF,UAAU,aAAoC;CACjD"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CompanyProfileFormStore = void 0;
13
+ const formstate_1 = require("formstate");
14
+ const form_1 = require("@servicetitan/form");
15
+ const react_ioc_1 = require("@servicetitan/react-ioc");
16
+ const validators_1 = require("../utils/validators");
17
+ const mobx_1 = require("mobx");
18
+ const required = (value) => (!value || value.length === 0) && 'cannot be empty string';
19
+ const usZipMask = '99999';
20
+ const canadaZipMask = '*** ***';
21
+ const canadaBNMask = '999999999';
22
+ const usEinMask = '99-9999999';
23
+ let CompanyProfileFormStore = class CompanyProfileFormStore {
24
+ constructor() {
25
+ Object.defineProperty(this, "showFormError", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: false
30
+ });
31
+ Object.defineProperty(this, "isInitializing", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: false
36
+ });
37
+ Object.defineProperty(this, "countries", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: []
42
+ });
43
+ Object.defineProperty(this, "countryAndRegionData", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: []
48
+ });
49
+ Object.defineProperty(this, "phoneMask", {
50
+ enumerable: true,
51
+ configurable: true,
52
+ writable: true,
53
+ value: ''
54
+ });
55
+ Object.defineProperty(this, "regionToCodeMap", {
56
+ enumerable: true,
57
+ configurable: true,
58
+ writable: true,
59
+ value: new Map()
60
+ });
61
+ Object.defineProperty(this, "form", {
62
+ enumerable: true,
63
+ configurable: true,
64
+ writable: true,
65
+ value: new formstate_1.FormState({
66
+ companyName: new form_1.InputFieldState('').validators(required),
67
+ adminPhone: new form_1.InputFieldState(''),
68
+ companyStreetAddress: new form_1.InputFieldState('').validators(required),
69
+ companyCountry: new form_1.DropdownFieldState('').validators(required),
70
+ companyStateCode: new form_1.DropdownFieldState('').validators(required),
71
+ companyCity: new form_1.InputFieldState('').validators(required),
72
+ companyZipCode: new form_1.InputFieldState('').validators(required),
73
+ einOrBn: new form_1.InputFieldState(''),
74
+ })
75
+ });
76
+ Object.defineProperty(this, "setFormErrorCheck", {
77
+ enumerable: true,
78
+ configurable: true,
79
+ writable: true,
80
+ value: (value) => {
81
+ this.showFormError = value;
82
+ }
83
+ });
84
+ Object.defineProperty(this, "isCanada", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: (country) => {
89
+ const lowerCountry = country === null || country === void 0 ? void 0 : country.toLowerCase();
90
+ return lowerCountry === 'ca' || lowerCountry === 'canada';
91
+ }
92
+ });
93
+ Object.defineProperty(this, "initForm", {
94
+ enumerable: true,
95
+ configurable: true,
96
+ writable: true,
97
+ value: (formData, options) => {
98
+ this.form.$.adminPhone.validators(validators_1.PhoneValidator(options.phonePattern, false));
99
+ this.countries = options.countries;
100
+ this.countryAndRegionData = options.countryAndRegionData;
101
+ this.phoneMask = options.phoneMask;
102
+ this.regionToCodeMap = options.regionToCodeMap;
103
+ form_1.setFormStateValues(this.form, formData);
104
+ form_1.commitFormState(this.form);
105
+ }
106
+ });
107
+ Object.defineProperty(this, "commitForm", {
108
+ enumerable: true,
109
+ configurable: true,
110
+ writable: true,
111
+ value: () => form_1.commitFormState(this.form)
112
+ });
113
+ mobx_1.makeObservable(this);
114
+ this.form.$.companyZipCode.validators(($) => {
115
+ const country = this.form.$.companyCountry.value;
116
+ const zip = ($ || '').toLowerCase().replace(/ /g, '');
117
+ return this.isCanada(country)
118
+ ? !/^[0-9A-Za-z]{6}$/.test(zip) && 'Invalid Zip Code'
119
+ : !/^\d{5}$/.test(zip) && 'Invalid Zip Code';
120
+ });
121
+ this.form.$.einOrBn.validators(($) => {
122
+ const errorMessage = `Invalid ${this.isCanada(this.form.$.companyCountry.value) ? 'BN' : 'EIN'}`;
123
+ return $ && $.length !== 9 && errorMessage;
124
+ });
125
+ }
126
+ get zipCodeMask() {
127
+ return this.isCanada(this.form.$.companyCountry.$) ? canadaZipMask : usZipMask;
128
+ }
129
+ get einOrBnMask() {
130
+ return this.isCanada(this.form.$.companyCountry.$) ? canadaBNMask : usEinMask;
131
+ }
132
+ get einOrBnInputProps() {
133
+ return this.isCanada(this.form.$.companyCountry.$)
134
+ ? {
135
+ label: 'BN Number',
136
+ placeholder: 'XXXXXXXXX',
137
+ }
138
+ : {
139
+ label: 'EIN Number',
140
+ placeholder: 'XX-XXXXXXX',
141
+ };
142
+ }
143
+ };
144
+ __decorate([
145
+ mobx_1.observable,
146
+ __metadata("design:type", Object)
147
+ ], CompanyProfileFormStore.prototype, "showFormError", void 0);
148
+ __decorate([
149
+ mobx_1.observable,
150
+ __metadata("design:type", Object)
151
+ ], CompanyProfileFormStore.prototype, "isInitializing", void 0);
152
+ __decorate([
153
+ mobx_1.observable,
154
+ __metadata("design:type", Array)
155
+ ], CompanyProfileFormStore.prototype, "countries", void 0);
156
+ __decorate([
157
+ mobx_1.observable,
158
+ __metadata("design:type", Array)
159
+ ], CompanyProfileFormStore.prototype, "countryAndRegionData", void 0);
160
+ __decorate([
161
+ mobx_1.observable,
162
+ __metadata("design:type", Object)
163
+ ], CompanyProfileFormStore.prototype, "phoneMask", void 0);
164
+ __decorate([
165
+ mobx_1.observable,
166
+ __metadata("design:type", Map)
167
+ ], CompanyProfileFormStore.prototype, "regionToCodeMap", void 0);
168
+ __decorate([
169
+ mobx_1.action,
170
+ __metadata("design:type", Object)
171
+ ], CompanyProfileFormStore.prototype, "setFormErrorCheck", void 0);
172
+ __decorate([
173
+ mobx_1.computed,
174
+ __metadata("design:type", Object),
175
+ __metadata("design:paramtypes", [])
176
+ ], CompanyProfileFormStore.prototype, "zipCodeMask", null);
177
+ __decorate([
178
+ mobx_1.computed,
179
+ __metadata("design:type", Object),
180
+ __metadata("design:paramtypes", [])
181
+ ], CompanyProfileFormStore.prototype, "einOrBnMask", null);
182
+ __decorate([
183
+ mobx_1.computed,
184
+ __metadata("design:type", Object),
185
+ __metadata("design:paramtypes", [])
186
+ ], CompanyProfileFormStore.prototype, "einOrBnInputProps", null);
187
+ __decorate([
188
+ mobx_1.action,
189
+ __metadata("design:type", Object)
190
+ ], CompanyProfileFormStore.prototype, "initForm", void 0);
191
+ __decorate([
192
+ mobx_1.action,
193
+ __metadata("design:type", Object)
194
+ ], CompanyProfileFormStore.prototype, "commitForm", void 0);
195
+ CompanyProfileFormStore = __decorate([
196
+ react_ioc_1.injectable(),
197
+ __metadata("design:paramtypes", [])
198
+ ], CompanyProfileFormStore);
199
+ exports.CompanyProfileFormStore = CompanyProfileFormStore;
200
+ //# sourceMappingURL=company-profile-form.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-profile-form.store.js","sourceRoot":"","sources":["../../../src/company-profile/stores/company-profile-form.store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const PhoneValidator: (pattern: RegExp, required: boolean) => ($: string) => false | "" | "Invalid phone number";
2
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../../src/company-profile/utils/validators.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,YAAa,MAAM,YAAY,OAAO,SAClD,MAAM,wCASpB,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PhoneValidator = void 0;
4
+ const PhoneValidator = (pattern, required) => {
5
+ return ($) => {
6
+ const phoneString = ($ || '').replace(/[^0-9.]/g, '');
7
+ const isRequired = !required ? phoneString : true;
8
+ return (isRequired &&
9
+ !pattern.test(phoneString.replace(/[^0-9.]/g, '')) &&
10
+ 'Invalid phone number');
11
+ };
12
+ };
13
+ exports.PhoneValidator = PhoneValidator;
14
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/company-profile/utils/validators.ts"],"names":[],"mappings":";;;AAAO,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,QAAiB,EAAE,EAAE;IACjE,OAAO,CAAC,CAAS,EAAE,EAAE;QACjB,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;QAClD,OAAO,CACH,UAAU;YACV,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAClD,sBAAsB,CACzB,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC;AAVW,QAAA,cAAc,kBAUzB"}
@@ -0,0 +1,2 @@
1
+ export * from './company-profile';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./company-profile"), exports);
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAkC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@servicetitan/onboarding-ui",
3
+ "version": "1.1.0",
4
+ "description": "Shared components between servicetitan monolith and Onboarding",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/servicetitan/anvil-uikit-contrib",
8
+ "directory": "packages/onboarding-ui"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "typings": "./dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ],
16
+ "peerDependencies": {
17
+ "@servicetitan/confirm": "~14.3.0",
18
+ "@servicetitan/culture": "~14.3.0",
19
+ "@servicetitan/data-query": "~14.3.0",
20
+ "@servicetitan/design-system": "~10.1.1",
21
+ "@servicetitan/form": "~14.3.0",
22
+ "@servicetitan/react-ioc": "~14.3.0",
23
+ "axios": "~0.21.1",
24
+ "formstate": "~2.0.0",
25
+ "mobx": "~6.3.2",
26
+ "mobx-react": "~7.2.0",
27
+ "react": "~17.0.2",
28
+ "react-dom": "~17.0.1",
29
+ "resumablejs": "~1.0.2"
30
+ },
31
+ "devDependencies": {
32
+ "@servicetitan/confirm": "~14.3.0",
33
+ "@servicetitan/culture": "~14.3.0",
34
+ "@servicetitan/data-query": "~14.3.0",
35
+ "@servicetitan/design-system": "~10.1.1",
36
+ "@servicetitan/form": "~14.3.0",
37
+ "@servicetitan/react-ioc": "~14.3.0",
38
+ "@types/react": "~17.0.15",
39
+ "@types/react-dom": "~17.0.0",
40
+ "axios": "~0.21.1",
41
+ "formstate": "~2.0.0",
42
+ "mobx": "~6.3.2",
43
+ "mobx-react": "~7.2.0",
44
+ "react": "~17.0.2",
45
+ "react-dom": "~17.0.1",
46
+ "resumablejs": "~1.0.2"
47
+ },
48
+ "dependencies": {
49
+ "classnames": "~2.3.1"
50
+ },
51
+ "keywords": [
52
+ "companyProfile"
53
+ ],
54
+ "author": "Suman Lama",
55
+ "license": "ISC",
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "cli": {
60
+ "less": true,
61
+ "webpack": false
62
+ },
63
+ "gitHead": "67ee035810f83c8ee85519f18ee746a7417f1c6d"
64
+ }
@@ -0,0 +1,140 @@
1
+ import React from 'react';
2
+ import { Form, FormDropdownProps } from '@servicetitan/design-system';
3
+ import classNames from 'classnames';
4
+ import { CountryDropdownInput } from './country-dropdown-input';
5
+ import { observer } from 'mobx-react';
6
+ import { useDependencies } from '@servicetitan/react-ioc';
7
+ import { StateAndProvinceDropdownInput } from './state-and-province-dropdown-input';
8
+ import { CompanyProfileFormStore } from '../stores/company-profile-form.store';
9
+ import { MaskedInput } from '@servicetitan/form';
10
+
11
+ export const CompanyProfileForm = observer((props: { className?: string }) => {
12
+ const [store] = useDependencies(CompanyProfileFormStore);
13
+
14
+ const { form, showFormError, zipCodeMask, einOrBnMask, einOrBnInputProps } = store;
15
+
16
+ const zipCodeOnChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
17
+ form.$.companyZipCode.onChangeHandler(e, {
18
+ value: e.target.value,
19
+ });
20
+ };
21
+
22
+ const einOrBnOnChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
23
+ form.$.einOrBn.onChangeHandler(e, {
24
+ value: (e.target.value || '').replace(/[^0-9.]/g, ''),
25
+ });
26
+ };
27
+
28
+ const phoneOnChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
29
+ form.$.adminPhone.onChangeHandler(e, { value: e.target.value });
30
+ };
31
+
32
+ const countryOnChangeHandler = (
33
+ event: React.SyntheticEvent<HTMLElement>,
34
+ data: FormDropdownProps
35
+ ) => {
36
+ if (form.$.companyCountry.$ && data.value !== form.$.companyCountry.$) {
37
+ form.$.companyStateCode.onChange('');
38
+ }
39
+ form.$.companyCountry.onChangeHandler(event, data);
40
+ };
41
+
42
+ const {
43
+ companyName,
44
+ companyStreetAddress,
45
+ companyCity,
46
+ companyCountry,
47
+ companyStateCode,
48
+ companyZipCode,
49
+ adminPhone,
50
+ einOrBn,
51
+ } = store.form.$;
52
+
53
+ const zipCodeHasError = companyZipCode.hasError;
54
+
55
+ return (
56
+ <Form size="tiny" className={classNames(props.className, 'ta-left', 'p-x-6')}>
57
+ <Form.Input
58
+ label="Company Name"
59
+ placeholder="Company Name"
60
+ value={companyName.value}
61
+ onChange={companyName.onChangeHandler}
62
+ error={(companyName.dirty || showFormError) && companyName.hasError}
63
+ />
64
+ <Form.Input
65
+ label="Street Address"
66
+ placeholder="Street Address"
67
+ value={companyStreetAddress.value}
68
+ onChange={companyStreetAddress.onChangeHandler}
69
+ error={
70
+ (companyStreetAddress.dirty || showFormError) && companyStreetAddress.hasError
71
+ }
72
+ />
73
+ <Form.Group width="equal">
74
+ <Form.Input
75
+ fluid
76
+ label="City"
77
+ placeholder="City"
78
+ className="p-r-0"
79
+ width="6"
80
+ value={companyCity.value}
81
+ onChange={companyCity.onChangeHandler}
82
+ error={(companyCity.dirty || showFormError) && companyCity.hasError}
83
+ />
84
+ <StateAndProvinceDropdownInput
85
+ width="6"
86
+ countryCode={companyCountry.value || 'USA'}
87
+ fieldState={companyStateCode}
88
+ error={(companyStateCode.dirty || showFormError) && companyStateCode.hasError}
89
+ countryAndRegionData={store.countryAndRegionData}
90
+ regionNameToCodeMap={store.regionToCodeMap}
91
+ />
92
+ </Form.Group>
93
+ <Form.Group width="equal">
94
+ <MaskedInput
95
+ fluid
96
+ label="ZIP Code"
97
+ placeholder="ZIP Code"
98
+ value={companyZipCode.value}
99
+ onChange={zipCodeOnChangeHandler}
100
+ mask={zipCodeMask}
101
+ className="p-r-0"
102
+ maskChar=" "
103
+ error={(companyZipCode.dirty || showFormError) && zipCodeHasError}
104
+ width={6}
105
+ />
106
+ <CountryDropdownInput
107
+ width="6"
108
+ value={companyCountry.value}
109
+ onChange={countryOnChangeHandler}
110
+ error={(companyCountry.dirty || showFormError) && companyCountry.hasError}
111
+ options={store.countries.map(x => ({ key: x, value: x, text: x }))}
112
+ />
113
+ </Form.Group>
114
+ <Form.Group width="equal">
115
+ <MaskedInput
116
+ fluid
117
+ label="Phone Number"
118
+ placeholder="Phone Number"
119
+ value={adminPhone.value}
120
+ onChange={phoneOnChangeHandler}
121
+ error={(adminPhone.dirty || showFormError) && adminPhone.hasError}
122
+ mask={store.phoneMask}
123
+ width={6}
124
+ />
125
+ <MaskedInput
126
+ fluid
127
+ label={einOrBnInputProps.label}
128
+ placeholder={einOrBnInputProps.placeholder}
129
+ value={einOrBn.value}
130
+ onChange={einOrBnOnChangeHandler}
131
+ mask={einOrBnMask}
132
+ className="p-r-0"
133
+ maskChar=" "
134
+ error={(einOrBn.dirty || showFormError) && einOrBn.hasError}
135
+ width={6}
136
+ />
137
+ </Form.Group>
138
+ </Form>
139
+ );
140
+ });
@@ -0,0 +1,7 @@
1
+ .company-profile-container {
2
+ max-width: 650px !important;
3
+ }
4
+
5
+ .company-profile-form {
6
+ margin-bottom: 9px;
7
+ }
@@ -0,0 +1,4 @@
1
+ export const __esModule: true;
2
+ export const companyProfileContainer: string;
3
+ export const companyProfileForm: string;
4
+
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { FormDropdownProps, Form, SemanticWIDTHS } from '@servicetitan/design-system';
3
+ import { observer } from 'mobx-react';
4
+ import { Option } from '@servicetitan/form';
5
+
6
+ export interface ICountryDropdownInput extends FormDropdownProps {
7
+ options: Option<string>[];
8
+ width?: SemanticWIDTHS;
9
+ }
10
+
11
+ export const CountryDropdownInput = observer((props: ICountryDropdownInput) => {
12
+ const value = props.value && props.value!.toString().toLowerCase();
13
+ const country = value && (value === 'canada' || value === 'ca' ? 'Canada' : 'USA');
14
+ return (
15
+ <Form.Select
16
+ fluid
17
+ search
18
+ width={props.width ?? '12'}
19
+ label="Country"
20
+ placeholder={props.placeholder ?? 'Country'}
21
+ className={props.className}
22
+ value={country}
23
+ onChange={props.onChange}
24
+ options={props.options}
25
+ error={props.error}
26
+ />
27
+ );
28
+ });
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { Form, FormDropdownProps, SemanticWIDTHS } from '@servicetitan/design-system';
3
+ import { observer } from 'mobx-react';
4
+ import { DropdownFieldState } from '@servicetitan/form';
5
+ import { CountryWithRegions, DropdownRegion } from '../stores/company-profile-form.store';
6
+
7
+ interface StateAndProvinceDropdownInputProps extends FormDropdownProps {
8
+ countryCode: string;
9
+ fieldState: DropdownFieldState<string>;
10
+ countryAndRegionData: CountryWithRegions[];
11
+ regionNameToCodeMap: Map<string, string>;
12
+ width?: SemanticWIDTHS;
13
+ }
14
+
15
+ const toTitleCase = (str: string) =>
16
+ str.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
17
+
18
+ export const StateAndProvinceDropdownInput = observer(
19
+ (props: StateAndProvinceDropdownInputProps) => {
20
+ const { value, onChange, onChangeHandler } = props.fieldState;
21
+
22
+ React.useEffect(() => {
23
+ /*
24
+ * requirement: convert any incoming state value that is a full state/province name
25
+ * to it's respective state code (e.g. 'Alabama' => 'AL')
26
+ * The incoming value may not have proper casing
27
+ * (salesforce data input through text input field not dropdown),
28
+ * so convert to proper casing to find value in map
29
+ * https://servicetitan.atlassian.net/browse/OX-948
30
+ */
31
+ if (value && value.length > 2) {
32
+ onChange(props.regionNameToCodeMap.get(toTitleCase(value)) ?? ' ');
33
+ }
34
+ }, [onChange, props.regionNameToCodeMap, value]);
35
+
36
+ let americanRegionalData;
37
+ let canadianRegionalData;
38
+
39
+ props.countryAndRegionData.forEach((countryOption: CountryWithRegions) => {
40
+ const data = countryOption.Regions.map((option: DropdownRegion) => ({
41
+ key: option.Code,
42
+ value: option.Code,
43
+ text: option.Name,
44
+ }));
45
+ if (countryOption.Country === 'US') {
46
+ americanRegionalData = data;
47
+ }
48
+ if (countryOption.Country === 'CA') {
49
+ canadianRegionalData = data;
50
+ }
51
+ });
52
+
53
+ const regionType =
54
+ props.countryCode.toLowerCase() === 'canada' || props.countryCode.toLowerCase() === 'ca'
55
+ ? 'Province'
56
+ : 'State';
57
+ const options = regionType === 'Province' ? canadianRegionalData : americanRegionalData;
58
+
59
+ return (
60
+ <Form.Select
61
+ search
62
+ fluid
63
+ width={props.width ?? '12'}
64
+ label={regionType}
65
+ placeholder={props.placeholder ?? regionType}
66
+ className={props.className}
67
+ value={value}
68
+ onChange={onChangeHandler}
69
+ options={options!}
70
+ error={props.error}
71
+ />
72
+ );
73
+ }
74
+ );
@@ -0,0 +1,6 @@
1
+ export * from './components/company-profile-form';
2
+ export * from './components/country-dropdown-input';
3
+ export * from './components/state-and-province-dropdown-input';
4
+ export * from './stores/company-profile-form.store';
5
+ export * from './stores/__mocks__/company-profile-form-mock-data';
6
+ export * from './utils/validators';
@@ -0,0 +1,32 @@
1
+ import { ProfileModel } from '../company-profile-form.store';
2
+
3
+ export const CompanyProfileFormCorrect: ProfileModel = {
4
+ companyName: 'Wyatt Works',
5
+ adminPhone: '(310) 855-8585',
6
+ companyStreetAddress: '123 Main St.',
7
+ companyCountry: 'USA',
8
+ companyStateCode: 'CA',
9
+ companyCity: 'Glendale',
10
+ companyZipCode: '12345',
11
+ einOrBn: '',
12
+ };
13
+
14
+ export const CompanyProfileFormEmptyValues: ProfileModel = {
15
+ companyName: '',
16
+ adminPhone: '',
17
+ companyStreetAddress: '',
18
+ companyCountry: '',
19
+ companyStateCode: '',
20
+ companyCity: '',
21
+ companyZipCode: '',
22
+ };
23
+
24
+ export const CompanyProfileFormCanadian: ProfileModel = {
25
+ companyName: 'Wyatt Works',
26
+ adminPhone: '(310) 855-8585',
27
+ companyStreetAddress: '123 Main St.',
28
+ companyCountry: 'ca',
29
+ companyStateCode: 'CA',
30
+ companyCity: 'Glendale',
31
+ companyZipCode: '12345',
32
+ };
@@ -0,0 +1,41 @@
1
+ import { Container } from '@servicetitan/react-ioc';
2
+ import { CompanyProfileFormStore, ICompanyProfileFormStore } from '../company-profile-form.store';
3
+ import {
4
+ CompanyProfileFormCorrect,
5
+ CompanyProfileFormEmptyValues,
6
+ CompanyProfileFormCanadian,
7
+ } from '../__mocks__/company-profile-form-mock-data';
8
+
9
+ const rootContainer = new Container();
10
+ rootContainer.bind<ICompanyProfileFormStore>(CompanyProfileFormStore).toSelf();
11
+
12
+ const initContainer = () => {
13
+ const container = new Container();
14
+ container.parent = rootContainer;
15
+ return container;
16
+ };
17
+
18
+ describe('Company Profile Form Store [View Functionality] Tests', () => {
19
+ test('Should initialize correct data with no validation errors', async () => {
20
+ const container = initContainer();
21
+ const store = container.get(CompanyProfileFormStore);
22
+ store.initForm(CompanyProfileFormCorrect, { phonePattern: /(.*)/ } as any);
23
+ await store.form.validate();
24
+ expect(store.form.hasError).toBeFalsy();
25
+ });
26
+
27
+ test('Should initialize incorrect data with validation errors', async () => {
28
+ const container = initContainer();
29
+ const store = container.get(CompanyProfileFormStore);
30
+ store.initForm(CompanyProfileFormEmptyValues, { phonePattern: /(.*)/ } as any);
31
+ await store.form.validate();
32
+ expect(store.form.hasError).toBeTruthy();
33
+ });
34
+
35
+ test('Expect forms initialized with CompanyCountry set to Canada show correct phone masking', () => {
36
+ const container = initContainer();
37
+ const store = container.get(CompanyProfileFormStore);
38
+ store.initForm(CompanyProfileFormCanadian, { phonePattern: /(.*)/ } as any);
39
+ expect(store.zipCodeMask).toBe('*** ***');
40
+ });
41
+ });
@@ -0,0 +1,151 @@
1
+ import { FieldState, FormState } from 'formstate';
2
+ import {
3
+ InputFieldState,
4
+ DropdownFieldState,
5
+ commitFormState,
6
+ setFormStateValues,
7
+ } from '@servicetitan/form';
8
+ import { injectable } from '@servicetitan/react-ioc';
9
+ import { PhoneValidator } from '../utils/validators';
10
+ import { computed, action, observable, makeObservable } from 'mobx';
11
+
12
+ const required = (value: string) => (!value || value.length === 0) && 'cannot be empty string';
13
+
14
+ export interface DropdownRegion {
15
+ Code: string;
16
+ Name: string;
17
+ }
18
+
19
+ export interface CountryWithRegions {
20
+ Country: string;
21
+ Regions: DropdownRegion[];
22
+ }
23
+
24
+ export interface ProfileModel {
25
+ companyName?: string | undefined;
26
+ adminPhone?: string | undefined;
27
+ companyStreetAddress?: string | undefined;
28
+ companyCountry?: string | undefined;
29
+ companyStateCode?: string | undefined;
30
+ companyCity?: string | undefined;
31
+ companyZipCode?: string | undefined;
32
+ einOrBn?: string | undefined;
33
+ }
34
+
35
+ const usZipMask = '99999';
36
+ const canadaZipMask = '*** ***';
37
+ const canadaBNMask = '999999999';
38
+ const usEinMask = '99-9999999';
39
+
40
+ export interface ICompanyProfileFormType {
41
+ [key: string]: FieldState<any>;
42
+ companyName: InputFieldState<string>;
43
+ adminPhone: InputFieldState<string>;
44
+ companyStreetAddress: InputFieldState<string>;
45
+ companyCountry: DropdownFieldState<string>;
46
+ companyStateCode: DropdownFieldState<string>;
47
+ companyCity: InputFieldState<string>;
48
+ companyZipCode: InputFieldState<string>;
49
+ einOrBn: InputFieldState<string>;
50
+ }
51
+
52
+ export interface ICompanyProfileFormStore {
53
+ showFormError: boolean;
54
+ isInitializing: boolean;
55
+ form: FormState<ICompanyProfileFormType>;
56
+ }
57
+
58
+ interface CompanyProfileFormOptions {
59
+ phonePattern: RegExp;
60
+ countries: string[];
61
+ countryAndRegionData: CountryWithRegions[];
62
+ phoneMask: string;
63
+ regionToCodeMap: Map<string, string>;
64
+ }
65
+
66
+ @injectable()
67
+ export class CompanyProfileFormStore implements ICompanyProfileFormStore {
68
+ @observable showFormError = false;
69
+ @observable isInitializing = false;
70
+ @observable countries: string[] = [];
71
+ @observable countryAndRegionData: CountryWithRegions[] = [];
72
+ @observable phoneMask = '';
73
+ @observable regionToCodeMap: Map<string, string> = new Map();
74
+
75
+ form: FormState<ICompanyProfileFormType> = new FormState({
76
+ companyName: new InputFieldState('').validators(required),
77
+ adminPhone: new InputFieldState(''),
78
+ companyStreetAddress: new InputFieldState('').validators(required),
79
+ companyCountry: new DropdownFieldState('').validators(required),
80
+ companyStateCode: new DropdownFieldState('').validators(required),
81
+ companyCity: new InputFieldState('').validators(required),
82
+ companyZipCode: new InputFieldState('').validators(required),
83
+ einOrBn: new InputFieldState(''),
84
+ });
85
+
86
+ constructor() {
87
+ makeObservable(this);
88
+
89
+ this.form.$.companyZipCode.validators(($: string) => {
90
+ const country = this.form.$.companyCountry.value;
91
+ const zip = ($ || '').toLowerCase().replace(/ /g, '');
92
+ return this.isCanada(country)
93
+ ? !/^[0-9A-Za-z]{6}$/.test(zip) && 'Invalid Zip Code'
94
+ : !/^\d{5}$/.test(zip) && 'Invalid Zip Code';
95
+ });
96
+
97
+ this.form.$.einOrBn.validators(($: string) => {
98
+ const errorMessage = `Invalid ${
99
+ this.isCanada(this.form.$.companyCountry.value) ? 'BN' : 'EIN'
100
+ }`;
101
+ return $ && $.length !== 9 && errorMessage;
102
+ });
103
+ }
104
+
105
+ @action
106
+ setFormErrorCheck = (value: boolean) => {
107
+ this.showFormError = value;
108
+ };
109
+
110
+ isCanada = (country: string) => {
111
+ const lowerCountry = country?.toLowerCase();
112
+ return lowerCountry === 'ca' || lowerCountry === 'canada';
113
+ };
114
+
115
+ @computed
116
+ get zipCodeMask() {
117
+ return this.isCanada(this.form.$.companyCountry.$) ? canadaZipMask : usZipMask;
118
+ }
119
+
120
+ @computed
121
+ get einOrBnMask() {
122
+ return this.isCanada(this.form.$.companyCountry.$) ? canadaBNMask : usEinMask;
123
+ }
124
+
125
+ @computed
126
+ get einOrBnInputProps() {
127
+ return this.isCanada(this.form.$.companyCountry.$)
128
+ ? {
129
+ label: 'BN Number',
130
+ placeholder: 'XXXXXXXXX',
131
+ }
132
+ : {
133
+ label: 'EIN Number',
134
+ placeholder: 'XX-XXXXXXX',
135
+ };
136
+ }
137
+
138
+ @action
139
+ initForm = (formData: ProfileModel, options: CompanyProfileFormOptions) => {
140
+ this.form.$.adminPhone.validators(PhoneValidator(options.phonePattern, false));
141
+ this.countries = options.countries;
142
+ this.countryAndRegionData = options.countryAndRegionData;
143
+ this.phoneMask = options.phoneMask;
144
+ this.regionToCodeMap = options.regionToCodeMap;
145
+ setFormStateValues(this.form, formData);
146
+ commitFormState(this.form);
147
+ };
148
+
149
+ @action
150
+ commitForm = () => commitFormState(this.form);
151
+ }
@@ -0,0 +1,11 @@
1
+ export const PhoneValidator = (pattern: RegExp, required: boolean) => {
2
+ return ($: string) => {
3
+ const phoneString = ($ || '').replace(/[^0-9.]/g, '');
4
+ const isRequired = !required ? phoneString : true;
5
+ return (
6
+ isRequired &&
7
+ !pattern.test(phoneString.replace(/[^0-9.]/g, '')) &&
8
+ 'Invalid phone number'
9
+ );
10
+ };
11
+ };
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './company-profile';