From 2e49f30aeeb47de4d01ca3c10b98436dbbc5ed03 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Wed, 5 Jul 2023 21:48:19 -0300 Subject: [PATCH 01/24] Unsafe/incomplete implementation. Just saving working in progress --- package.json | 6 + .../components/QuoteDetails/QuoteDetails.tsx | 26 +- react/utils/metrics.ts | 86 ++++++ yarn.lock | 284 +++++++++++++++++- 4 files changed, 394 insertions(+), 8 deletions(-) create mode 100644 react/utils/metrics.ts diff --git a/package.json b/package.json index 64f0813..962f115 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,12 @@ "prettier --write" ] }, + "dependencies": { + "axios": "1.4.0", + "react": "^18.2.0", + "react-apollo": "^3.1.5", + "react-intl": "^6.4.4" + }, "devDependencies": { "@types/node": "12.12.21", "@vtex/prettier-config": "^0.3.1", diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index 5babd39..bcf10db 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -38,6 +38,8 @@ import AlertMessage from './AlertMessage' import QuoteTable from './QuoteTable' import QuoteUpdateHistory from './QuoteUpdateHistory' import { Status } from '../../utils/status' +import type { SessionProfile } from '../../utils/metrics' +import { sendMetric } from '../../utils/metrics' const localStore = storageFactory(() => localStorage) const MAX_DISCOUNT_PERCENTAGE = 99 @@ -178,7 +180,10 @@ const QuoteDetails: FunctionComponent = () => { }) } - const handleCreateQuote = (sendToSalesRep: boolean) => { + const handleCreateQuote = ( + sendToSalesRep: boolean, + sessionProfile: SessionProfile + ) => { const { orderForm } = orderFormData setUpdatingQuoteState(true) @@ -196,6 +201,8 @@ const QuoteDetails: FunctionComponent = () => { }) .then((result: any) => { if (result.data.createQuote) { + sendMetric(sessionProfile, result.data.createQuote) + toastMessage(quoteMessages.createSuccess) handleClearCart(orderForm.orderFormId).then(() => { setQuoteState(initialState) @@ -229,7 +236,10 @@ const QuoteDetails: FunctionComponent = () => { }) } - const createQuote = (sendToSalesRep: boolean) => { + const createQuote = ( + sendToSalesRep: boolean, + sessionProfile: SessionProfile + ) => { setSentToSalesRep(sendToSalesRep) if (!quoteState.referenceName) { setFormState({ @@ -237,7 +247,7 @@ const QuoteDetails: FunctionComponent = () => { errorMessage: formatMessage(quoteMessages.required), }) } else { - handleCreateQuote(sendToSalesRep) + handleCreateQuote(sendToSalesRep, sessionProfile) } } @@ -613,11 +623,17 @@ const QuoteDetails: FunctionComponent = () => { sentToSalesRep={sentToSalesRep} quoteState={quoteState} onSaveForLater={() => { - createQuote(false) + createQuote( + false, + sessionResponse?.namespaces?.profile + ) }} onSaveQuote={() => { if (isNewQuote) { - createQuote(!isSalesRep) + createQuote( + !isSalesRep, + sessionResponse?.namespaces?.profile + ) } else { handleSaveQuote() } diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts new file mode 100644 index 0000000..25bcf40 --- /dev/null +++ b/react/utils/metrics.ts @@ -0,0 +1,86 @@ +import axios from 'axios' + +const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' + +type Metric = { + name: 'b2b-suite-buyerorg-data' + kind: 'event' + description: 'Create Quotation Action - UI' + account: string +} + +type QuotationFieldsMetric = { + orgId: string + costId: string + buyerOrg: string + memberId: string + memberEmail: string + memberName: string + roleId: string + creationDate: string + quotationId: string + sendToSalesRep: boolean +} + +export type SessionProfile = { + id: string + email: string + firstName?: string + lastName?: string +} + +export type QuotenMetric = Metric & { fields: QuotationFieldsMetric } + +export const buildQuoteMetric = ( + sessionProfile: SessionProfile, + quoteId: string +): QuotenMetric => { + return null + // const metric: QuotenMetric = { + // name: 'b2b-suite-buyerorg-data', + // kind: 'event', + // description: 'Create Quotation Action - UI', + // account: , + // fields: { + // orgId: , + // costId: , + // buyerOrg: , + // memberId: sessionProfile.id, + // memberEmail: sessionProfile.email, + // memberName: `${sessionProfile.firstName} ${sessionProfile.lastName}`, + // roleId: , + // creationDate: (new Date()).toISOString(), + // quotationId: result.data.createQuote, + // sendToSalesRep + // } + + // } +} + +export const sendMetric = (sessionProfile: SessionProfile, quoteId: string) => { + try { + const metric = buildQuoteMetric(sessionProfile, quoteId) + + axios.post(ANALYTICS_URL, metric) + } catch (error) { + console.error('Unable to log metrics', error) // TODO-existe log no IO? + } +} + +// useQuery(GET_QUOTE, { +// variables: { id: params?.id }, +// ssr: false, +// skip: isNewQuote, +// }) + +// { +// "id": "a94efd50-1b76-11ee-83ab-0adc9b832d19", +// "referenceName": "Tesdte", +// "creatorEmail": "fernando.barros+sales.admin@vtex.com.br", +// "creatorRole": "sales-admin", +// "creationDate": "2023-07-05T20:58:20.208Z", +// "organization": "d9e51195-0c39-11ed-835d-0ac601682b29", +// "organizationName": "VTEX", +// "costCenterName": "VTEX SP", +// "__typename": "Quote" +// } diff --git a/yarn.lock b/yarn.lock index bf93c94..e5cfe9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,55 @@ # yarn lockfile v1 +"@apollo/react-common@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@apollo/react-common/-/react-common-3.1.4.tgz#ec13c985be23ea8e799c9ea18e696eccc97be345" + integrity sha512-X5Kyro73bthWSCBJUC5XYQqMnG0dLWuDZmVkzog9dynovhfiVCV4kPSdgSIkqnb++cwCzOVuQ4rDKVwo2XRzQA== + dependencies: + ts-invariant "^0.4.4" + tslib "^1.10.0" + +"@apollo/react-components@^3.1.5": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@apollo/react-components/-/react-components-3.1.5.tgz#040d2f35ce4947747efe16f76d59dcbd797ffdaf" + integrity sha512-c82VyUuE9VBnJB7bnX+3dmwpIPMhyjMwyoSLyQWPHxz8jK4ak30XszJtqFf4eC4hwvvLYa+Ou6X73Q8V8e2/jg== + dependencies: + "@apollo/react-common" "^3.1.4" + "@apollo/react-hooks" "^3.1.5" + prop-types "^15.7.2" + ts-invariant "^0.4.4" + tslib "^1.10.0" + +"@apollo/react-hoc@^3.1.5": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@apollo/react-hoc/-/react-hoc-3.1.5.tgz#6552d2fb4aafc59fdc8f4e353358b98b89cfab6f" + integrity sha512-jlZ2pvEnRevLa54H563BU0/xrYSgWQ72GksarxUzCHQW85nmn9wQln0kLBX7Ua7SBt9WgiuYQXQVechaaCulfQ== + dependencies: + "@apollo/react-common" "^3.1.4" + "@apollo/react-components" "^3.1.5" + hoist-non-react-statics "^3.3.0" + ts-invariant "^0.4.4" + tslib "^1.10.0" + +"@apollo/react-hooks@^3.1.5": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@apollo/react-hooks/-/react-hooks-3.1.5.tgz#7e710be52461255ae7fc0b3b9c2ece64299c10e6" + integrity sha512-y0CJ393DLxIIkksRup4nt+vSjxalbZBXnnXxYbviq/woj+zKa431zy0yT4LqyRKpFy9ahMIwxBnBwfwIoupqLQ== + dependencies: + "@apollo/react-common" "^3.1.4" + "@wry/equality" "^0.1.9" + ts-invariant "^0.4.4" + tslib "^1.10.0" + +"@apollo/react-ssr@^3.1.5": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@apollo/react-ssr/-/react-ssr-3.1.5.tgz#53703cd493afcde567acc6d5512cab03dafce6de" + integrity sha512-wuLPkKlctNn3u8EU8rlECyktpOUCeekFfb0KhIKknpGY6Lza2Qu0bThx7D9MIbVEzhKadNNrzLcpk0Y8/5UuWg== + dependencies: + "@apollo/react-common" "^3.1.4" + "@apollo/react-hooks" "^3.1.5" + tslib "^1.10.0" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -60,6 +109,76 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@formatjs/ecma402-abstract@1.17.0": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz#2ce191a3bde4c65c6684e03fa247062a4a294b9e" + integrity sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ== + dependencies: + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/fast-memoize@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" + integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== + dependencies: + tslib "^2.4.0" + +"@formatjs/icu-messageformat-parser@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.0.tgz#b0d58ce8c8f472969c96b5cd0b3ad5522d3a02b7" + integrity sha512-yT6at0qc0DANw9qM/TU8RZaCtfDXtj4pZM/IC2WnVU80yAcliS3KVDiuUt4jSQAeFL9JS5bc2hARnFmjPdA6qw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/icu-skeleton-parser" "1.6.0" + tslib "^2.4.0" + +"@formatjs/icu-skeleton-parser@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.0.tgz#0728be8b6b3656f1a4b8e6e5b0e02dffffc23c6c" + integrity sha512-eMmxNpoX/J1IPUjPGSZwo0Wh+7CEvdEMddP2Jxg1gQJXfGfht/FdW2D5XDFj3VMbOTUQlDIdZJY7uC6O6gjPoA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + tslib "^2.4.0" + +"@formatjs/intl-displaynames@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.5.0.tgz#32737088e7d943fb3e22140e64bb634e0ba05fcf" + integrity sha512-sg/nR8ILEdUl+2sWu6jc1nQ5s04yucGlH1RVfatW8TSJ5uG3Yy3vgigi8NNC/BuhcncUNPWqSpTCSI1hA+rhiw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/intl-listformat@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.0.tgz#fa8ac535d82fc716f052f2fd60eeaa7331362357" + integrity sha512-ifupb+balZUAF/Oh3QyGRqPRWGSKwWoMPR0cYZEG7r61SimD+m38oFQqVx/3Fp7LfQFF11m7IS+MlxOo2sKINA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/intl-localematcher@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz#63bbc37a7c3545a1bf1686072e51d9a3aed98d6b" + integrity sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw== + dependencies: + tslib "^2.4.0" + +"@formatjs/intl@2.9.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.9.0.tgz#e1335572af3ca8a53e136a78e866f1851a9718c2" + integrity sha512-Ym0trUoC/VO6wQu4YHa0H1VR2tEixFRmwZgADkDLm7nD+vv1Ob+/88mUAoT0pwvirFqYKgUKEwp1tFepqyqvVA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/intl-displaynames" "6.5.0" + "@formatjs/intl-listformat" "7.4.0" + intl-messageformat "10.5.0" + tslib "^2.4.0" + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -102,6 +221,14 @@ dependencies: any-observable "^0.3.0" +"@types/hoist-non-react-statics@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/json-schema@^7.0.7": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -122,6 +249,25 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/react@*", "@types/react@16 || 17 || 18": + version "18.2.14" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127" + integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + "@typescript-eslint/eslint-plugin@^4.14.1": version "4.32.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.32.0.tgz#46d2370ae9311092f2a6f7246d28357daf2d4e89" @@ -197,6 +343,13 @@ resolved "https://registry.yarnpkg.com/@vtex/prettier-config/-/prettier-config-0.3.6.tgz#31762608d9a59b815b6d4e963e439b12f1a12279" integrity sha512-nXE3BcMODomFK3EowfK+Hdj2qQRqB8JcdRv8yTREXnN9xq8DYKmH/dWB+RY/Hn3KozFLbygpZRbqYsiA6HDINQ== +"@wry/equality@^0.1.9": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" + integrity sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA== + dependencies: + tslib "^1.9.3" + acorn-jsx@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -336,11 +489,25 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + axe-core@^4.0.2: version "4.3.3" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== +axios@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -464,6 +631,13 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -509,6 +683,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + damerau-levenshtein@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" @@ -557,6 +736,11 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1033,6 +1217,20 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1171,6 +1369,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -1247,6 +1452,16 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +intl-messageformat@10.5.0: + version "10.5.0" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.0.tgz#86d11b15913ac954075b25253f5e669359f89538" + integrity sha512-AvojYuOaRb6r2veOKfTVpxH9TrmjSdc5iR9R5RgBwrDZYSmAAFVT+QLbW3C4V7Qsg0OguMp67Q/EoUkxZzXRGw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + tslib "^2.4.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -1595,7 +1810,7 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -1627,6 +1842,18 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -1974,6 +2201,11 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -1992,11 +2224,45 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-is@^16.8.1: +react-apollo@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-3.1.5.tgz#36692d393c47e7ccc37f0a885c7cc5a8b4961c91" + integrity sha512-xOxMqxORps+WHrUYbjVHPliviomefOpu5Sh35oO3osuOyPTxvrljdfTLGCggMhcXBsDljtS5Oy4g+ijWg3D4JQ== + dependencies: + "@apollo/react-common" "^3.1.4" + "@apollo/react-components" "^3.1.5" + "@apollo/react-hoc" "^3.1.5" + "@apollo/react-hooks" "^3.1.5" + "@apollo/react-ssr" "^3.1.5" + +react-intl@^6.4.4: + version "6.4.4" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.4.4.tgz#14b45ce046bfbb60c0e6d392d8ddc30e9ead5a4f" + integrity sha512-/C9Sl/5//ohfkNG6AWlJuf4BhTXsbzyk93K62A4zRhSPANyOGpKZ+fWhN+TLfFd5YjDUHy+exU/09y0w1bO4Xw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/intl" "2.9.0" + "@formatjs/intl-displaynames" "6.5.0" + "@formatjs/intl-listformat" "7.4.0" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/react" "16 || 17 || 18" + hoist-non-react-statics "^3.3.2" + intl-messageformat "10.5.0" + tslib "^2.4.0" + +react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -2349,6 +2615,13 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +ts-invariant@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" + integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA== + dependencies: + tslib "^1.9.3" + tsconfig-paths@^3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" @@ -2359,11 +2632,16 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.4.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" From 29b557737e22f731ae54c73bbd740a489b07a6ba Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 6 Jul 2023 19:56:06 -0300 Subject: [PATCH 02/24] Partial implementation --- .gitignore | 3 + package.json | 3 +- .../components/QuoteDetails/QuoteDetails.tsx | 7 +- react/utils/metrics.ts | 150 ++++++++++++------ yarn.lock | 12 ++ 5 files changed, 127 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 212430b..e547a94 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ node/node_modules react/package-lock.json node/package-lock.json node/node_modules + + +.vscode/ \ No newline at end of file diff --git a/package.json b/package.json index 962f115..c2c2896 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "axios": "1.4.0", "react": "^18.2.0", "react-apollo": "^3.1.5", - "react-intl": "^6.4.4" + "react-intl": "^6.4.4", + "@vtex/raccoon-next": "^0.5.0" }, "devDependencies": { "@types/node": "12.12.21", diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index bcf10db..dca3eee 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -38,7 +38,7 @@ import AlertMessage from './AlertMessage' import QuoteTable from './QuoteTable' import QuoteUpdateHistory from './QuoteUpdateHistory' import { Status } from '../../utils/status' -import type { SessionProfile } from '../../utils/metrics' +import type { SessionProfile, QuoteData } from '../../utils/metrics' import { sendMetric } from '../../utils/metrics' const localStore = storageFactory(() => localStorage) @@ -201,7 +201,10 @@ const QuoteDetails: FunctionComponent = () => { }) .then((result: any) => { if (result.data.createQuote) { - sendMetric(sessionProfile, result.data.createQuote) + console.error( + `--------------------------------------------DATA:${data}` + ) + sendMetric(sendToSalesRep, sessionProfile, result.data.createQuote) toastMessage(quoteMessages.createSuccess) handleClearCart(orderForm.orderFormId).then(() => { diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 25bcf40..38cdde3 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -1,4 +1,10 @@ import axios from 'axios' +import { useQuery } from 'react-apollo' +import { useAdmin } from '@vtex/raccoon-next' + +import GET_QUOTE from '../../graphql/getQuote.graphql' +import GET_COSTCENTERS_BY_ORGANIZATION_ID from '../graphql/getCostCentersByOrganizationId.graphql' +import GET_PERMISSIONS from '../../graphql/getPermissions.graphql' const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' @@ -9,16 +15,31 @@ type Metric = { account: string } -type QuotationFieldsMetric = { +export type QuoteData = { + id: string + referenceName: string + creatorEmail: string + creatorRole: string + creationDate: string + organization: string // buyOrg id + organizationName: string // buyOrg name + costCenterName: string +} + +type QuoteFieldsMetric = { orgId: string - costId: string - buyerOrg: string + costCenterId: string + costCenterName: string + buyerOrgId: string + buyerOrgName: string memberId: string memberEmail: string memberName: string roleId: string + roleName: string creationDate: string quotationId: string + quoteReferenceName: string sendToSalesRep: boolean } @@ -29,58 +50,97 @@ export type SessionProfile = { lastName?: string } -export type QuotenMetric = Metric & { fields: QuotationFieldsMetric } +type CostCenter = { + id: string + name: string +} + +type Role = { + id: string + name: string +} + +export type QuoteMetric = Metric & { fields: QuoteFieldsMetric } + +const getCostCenter = ( + buyOrgId: string, + costCenterName: string +): CostCenter => { + // const costCenters = useQuery( + // GET_COSTCENTERS_BY_ORGANIZATION_ID, + // { + // variables: { id: buyOrgId, search: costCenterName }, + // ssr: false, + // notifyOnNetworkStatusChange: true, + // } + // ).data as CostCenter[] + + // return costCenters?.[0] + + return { + id: 'teste', + name: 'teste', + } +} + +const getRole = (): Role => { + // const role = useQuery(GET_PERMISSIONS, { ssr: false }).data as Role + // return role + return { + id: 'teste', + name: 'teste', + } +} export const buildQuoteMetric = ( + sendToSalesRep: boolean, sessionProfile: SessionProfile, - quoteId: string -): QuotenMetric => { - return null - // const metric: QuotenMetric = { - // name: 'b2b-suite-buyerorg-data', - // kind: 'event', - // description: 'Create Quotation Action - UI', - // account: , - // fields: { - // orgId: , - // costId: , - // buyerOrg: , - // memberId: sessionProfile.id, - // memberEmail: sessionProfile.email, - // memberName: `${sessionProfile.firstName} ${sessionProfile.lastName}`, - // roleId: , - // creationDate: (new Date()).toISOString(), - // quotationId: result.data.createQuote, - // sendToSalesRep - // } + quoteId: string, + quote: QuoteData +): QuoteMetric => { + // const quote = useQuery(GET_QUOTE, { + // variables: { id: quoteId } + // }).data as QuoteData - // } + const costCenter = getCostCenter(quote.organization, quote.costCenterName) + const role = getRole() + + const metric: QuoteMetric = { + name: 'b2b-suite-buyerorg-data', + kind: 'event', + description: 'Create Quotation Action - UI', + account: 'TESTE', // useAdmin().account, + fields: { + orgId: quote.organization, + costCenterId: costCenter.id, + costCenterName: quote.costCenterName, + buyerOrgId: quote.organization, + buyerOrgName: quote.organizationName, + memberId: sessionProfile.id, + memberEmail: quote.creatorEmail, + memberName: `${sessionProfile.firstName} ${sessionProfile.lastName}`, + roleId: role.id, + roleName: role.name, + creationDate: new Date().toISOString(), + quotationId: quoteId, + quoteReferenceName: quote.referenceName, + sendToSalesRep, + }, + } + + return metric } -export const sendMetric = (sessionProfile: SessionProfile, quoteId: string) => { +export const sendMetric = ( + sendToSalesRep: boolean, + sessionProfile: SessionProfile, + quoteId: string +) => { try { - const metric = buildQuoteMetric(sessionProfile, quoteId) + const metric = buildQuoteMetric(sendToSalesRep, sessionProfile, quoteId) axios.post(ANALYTICS_URL, metric) } catch (error) { console.error('Unable to log metrics', error) // TODO-existe log no IO? } } - -// useQuery(GET_QUOTE, { -// variables: { id: params?.id }, -// ssr: false, -// skip: isNewQuote, -// }) - -// { -// "id": "a94efd50-1b76-11ee-83ab-0adc9b832d19", -// "referenceName": "Tesdte", -// "creatorEmail": "fernando.barros+sales.admin@vtex.com.br", -// "creatorRole": "sales-admin", -// "creationDate": "2023-07-05T20:58:20.208Z", -// "organization": "d9e51195-0c39-11ed-835d-0ac601682b29", -// "organizationName": "VTEX", -// "costCenterName": "VTEX SP", -// "__typename": "Quote" -// } diff --git a/yarn.lock b/yarn.lock index e5cfe9a..d0457c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -343,6 +343,18 @@ resolved "https://registry.yarnpkg.com/@vtex/prettier-config/-/prettier-config-0.3.6.tgz#31762608d9a59b815b6d4e963e439b12f1a12279" integrity sha512-nXE3BcMODomFK3EowfK+Hdj2qQRqB8JcdRv8yTREXnN9xq8DYKmH/dWB+RY/Hn3KozFLbygpZRbqYsiA6HDINQ== +"@vtex/raccoon-next@^0.5.0": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@vtex/raccoon-next/-/raccoon-next-0.5.12.tgz#53f8674cf9dfdda59aed212b0ce8f370c99fa16f" + integrity sha512-pCyCon/QHbKB0lg8oWbdNK1cdWJQhAhzcaBQazi4+MCstT1fx23Gmv7BRIePtfZ6ovJWesEreripxBDssMzszw== + dependencies: + "@vtex/raccoon-shared-types" "^0.2.12" + +"@vtex/raccoon-shared-types@^0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@vtex/raccoon-shared-types/-/raccoon-shared-types-0.2.12.tgz#29992bbb71c5c5842e965271e44394298ca2cdcc" + integrity sha512-vNgPRRH3O3vGziCJC+iY+nYSH10/5GYIC+UwVzfjWm3DT6w/GAh6WPgYXGzQpGeEhbDhPuYdeESR0eZrFt3FbQ== + "@wry/equality@^0.1.9": version "0.1.11" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" From d1ab98e23ff4f459450343179fbaa0cd085c245e Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Wed, 12 Jul 2023 20:35:07 -0300 Subject: [PATCH 03/24] Include analytics metric for creation quote --- .../components/QuoteDetails/QuoteDetails.tsx | 59 +++++--- react/package.json | 3 +- react/utils/metrics.ts | 134 ++++++------------ react/yarn.lock | 30 +++- 4 files changed, 110 insertions(+), 116 deletions(-) diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index dca3eee..70187ed 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -29,6 +29,9 @@ import UPDATE_QUOTE from '../../graphql/updateQuote.graphql' import USE_QUOTE from '../../graphql/useQuote.graphql' import GET_AUTH_RULES from '../../graphql/getDimension.graphql' import CLEAR_CART from '../../graphql/clearCartMutation.graphql' +import CHECK_PERMISSIONS from '../../graphql/checkPermissions.graphql' +import GET_COSTCENTER_BY_ID from '../../graphql/getCostCenter.graphql' +import GET_ORGANIZATION_BY_ID from '../../graphql/getOrganization.graphql' import storageFactory from '../../utils/storage' import PercentageDiscount from './PercentageDiscount' import QuoteName from './QuoteName' @@ -38,7 +41,7 @@ import AlertMessage from './AlertMessage' import QuoteTable from './QuoteTable' import QuoteUpdateHistory from './QuoteUpdateHistory' import { Status } from '../../utils/status' -import type { SessionProfile, QuoteData } from '../../utils/metrics' +import type { SessionProfile } from '../../utils/metrics' import { sendMetric } from '../../utils/metrics' const localStore = storageFactory(() => localStorage) @@ -114,6 +117,21 @@ const QuoteDetails: FunctionComponent = () => { /** * GraphQL Queries */ + const userEmail = sessionResponse?.namespaces?.profile?.email?.value + const { data: userData } = useQuery(CHECK_PERMISSIONS, { + variables: { email: userEmail }, + }) + + const costCenterId: string = userData?.getUserByEmail?.[0]?.costId + const { data: costCenterData } = useQuery(GET_COSTCENTER_BY_ID, { + variables: { id: costCenterId }, + }) + + const orgId: string = userData?.getUserByEmail?.[0]?.orgId + const { data: organizationData } = useQuery(GET_ORGANIZATION_BY_ID, { + variables: { id: orgId }, + }) + const { data, loading, refetch } = useQuery(GET_QUOTE, { variables: { id: params?.id }, ssr: false, @@ -180,10 +198,7 @@ const QuoteDetails: FunctionComponent = () => { }) } - const handleCreateQuote = ( - sendToSalesRep: boolean, - sessionProfile: SessionProfile - ) => { + const handleCreateQuote = (sendToSalesRep: boolean) => { const { orderForm } = orderFormData setUpdatingQuoteState(true) @@ -201,10 +216,19 @@ const QuoteDetails: FunctionComponent = () => { }) .then((result: any) => { if (result.data.createQuote) { - console.error( - `--------------------------------------------DATA:${data}` - ) - sendMetric(sendToSalesRep, sessionProfile, result.data.createQuote) + const metricsParam = { + sessionProfile: sessionResponse?.namespaces + ?.profile as SessionProfile, + accountName: sessionResponse?.namespaces?.account?.accountName + ?.value as string, + userData: userData?.getUserByEmail?.[0], + costCenterName: costCenterData?.getCostCenterById?.name, + buyOrgName: organizationData?.getOrganizationById?.name, + quoteId: result.data.createQuote, + quoteReferenceName: quoteState.referenceName, + } + + sendMetric(sendToSalesRep, metricsParam) toastMessage(quoteMessages.createSuccess) handleClearCart(orderForm.orderFormId).then(() => { @@ -239,10 +263,7 @@ const QuoteDetails: FunctionComponent = () => { }) } - const createQuote = ( - sendToSalesRep: boolean, - sessionProfile: SessionProfile - ) => { + const createQuote = (sendToSalesRep: boolean) => { setSentToSalesRep(sendToSalesRep) if (!quoteState.referenceName) { setFormState({ @@ -250,7 +271,7 @@ const QuoteDetails: FunctionComponent = () => { errorMessage: formatMessage(quoteMessages.required), }) } else { - handleCreateQuote(sendToSalesRep, sessionProfile) + handleCreateQuote(sendToSalesRep) } } @@ -626,17 +647,11 @@ const QuoteDetails: FunctionComponent = () => { sentToSalesRep={sentToSalesRep} quoteState={quoteState} onSaveForLater={() => { - createQuote( - false, - sessionResponse?.namespaces?.profile - ) + createQuote(false) }} onSaveQuote={() => { if (isNewQuote) { - createQuote( - !isSalesRep, - sessionResponse?.namespaces?.profile - ) + createQuote(!isSalesRep) } else { handleSaveQuote() } diff --git a/react/package.json b/react/package.json index e8fd653..fe179b9 100644 --- a/react/package.json +++ b/react/package.json @@ -10,7 +10,8 @@ "graphql": "^14.5.8", "react": "^16.9.2", "react-apollo": "^3.1.5", - "react-intl": "^5.13.4" + "react-intl": "^5.13.4", + "axios": "1.4.0" }, "devDependencies": { "@types/jest": "^24.0.18", diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 38cdde3..fed20c2 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -1,44 +1,45 @@ import axios from 'axios' -import { useQuery } from 'react-apollo' -import { useAdmin } from '@vtex/raccoon-next' - -import GET_QUOTE from '../../graphql/getQuote.graphql' -import GET_COSTCENTERS_BY_ORGANIZATION_ID from '../graphql/getCostCentersByOrganizationId.graphql' -import GET_PERMISSIONS from '../../graphql/getPermissions.graphql' const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' +export type UserData = { + id: string + canImpersonate: boolean + orgId: string + clId: string + costId: string + roleId: string +} + +export type MetricsParam = { + sessionProfile: SessionProfile + accountName: string + userData: UserData + costCenterName: string + buyOrgName: string + quoteId: string + quoteReferenceName: string +} + type Metric = { name: 'b2b-suite-buyerorg-data' - kind: 'event' + kind: 'create-quote-ui-event' description: 'Create Quotation Action - UI' account: string } -export type QuoteData = { - id: string - referenceName: string - creatorEmail: string - creatorRole: string - creationDate: string - organization: string // buyOrg id - organizationName: string // buyOrg name - costCenterName: string -} - type QuoteFieldsMetric = { orgId: string costCenterId: string costCenterName: string - buyerOrgId: string - buyerOrgName: string + buyOrgId: string + buyOrgName: string memberId: string memberEmail: string memberName: string - roleId: string - roleName: string + role: string creationDate: string - quotationId: string + quoteId: string quoteReferenceName: string sendToSalesRep: boolean } @@ -50,80 +51,30 @@ export type SessionProfile = { lastName?: string } -type CostCenter = { - id: string - name: string -} - -type Role = { - id: string - name: string -} - export type QuoteMetric = Metric & { fields: QuoteFieldsMetric } -const getCostCenter = ( - buyOrgId: string, - costCenterName: string -): CostCenter => { - // const costCenters = useQuery( - // GET_COSTCENTERS_BY_ORGANIZATION_ID, - // { - // variables: { id: buyOrgId, search: costCenterName }, - // ssr: false, - // notifyOnNetworkStatusChange: true, - // } - // ).data as CostCenter[] - - // return costCenters?.[0] - - return { - id: 'teste', - name: 'teste', - } -} - -const getRole = (): Role => { - // const role = useQuery(GET_PERMISSIONS, { ssr: false }).data as Role - // return role - return { - id: 'teste', - name: 'teste', - } -} - export const buildQuoteMetric = ( sendToSalesRep: boolean, - sessionProfile: SessionProfile, - quoteId: string, - quote: QuoteData + metricsParam: MetricsParam ): QuoteMetric => { - // const quote = useQuery(GET_QUOTE, { - // variables: { id: quoteId } - // }).data as QuoteData - - const costCenter = getCostCenter(quote.organization, quote.costCenterName) - const role = getRole() - const metric: QuoteMetric = { name: 'b2b-suite-buyerorg-data', - kind: 'event', + kind: 'create-quote-ui-event', description: 'Create Quotation Action - UI', - account: 'TESTE', // useAdmin().account, + account: metricsParam.accountName, fields: { - orgId: quote.organization, - costCenterId: costCenter.id, - costCenterName: quote.costCenterName, - buyerOrgId: quote.organization, - buyerOrgName: quote.organizationName, - memberId: sessionProfile.id, - memberEmail: quote.creatorEmail, - memberName: `${sessionProfile.firstName} ${sessionProfile.lastName}`, - roleId: role.id, - roleName: role.name, + orgId: metricsParam.userData?.orgId, + costCenterId: metricsParam.userData?.costId, + costCenterName: metricsParam.costCenterName, + buyOrgId: metricsParam.userData.orgId, + buyOrgName: metricsParam.buyOrgName, + memberId: metricsParam.sessionProfile?.id, + memberEmail: metricsParam.sessionProfile?.email, + memberName: `${metricsParam.sessionProfile.firstName} ${metricsParam.sessionProfile.lastName}`, + role: metricsParam.userData?.roleId, creationDate: new Date().toISOString(), - quotationId: quoteId, - quoteReferenceName: quote.referenceName, + quoteId: metricsParam.quoteId, + quoteReferenceName: metricsParam.quoteReferenceName, sendToSalesRep, }, } @@ -131,16 +82,15 @@ export const buildQuoteMetric = ( return metric } -export const sendMetric = ( +export const sendMetric = async ( sendToSalesRep: boolean, - sessionProfile: SessionProfile, - quoteId: string + metricsParam: MetricsParam ) => { try { - const metric = buildQuoteMetric(sendToSalesRep, sessionProfile, quoteId) + const metric = buildQuoteMetric(sendToSalesRep, metricsParam) axios.post(ANALYTICS_URL, metric) } catch (error) { - console.error('Unable to log metrics', error) // TODO-existe log no IO? + console.error('Unable to log metrics', error) } } diff --git a/react/yarn.lock b/react/yarn.lock index 64c3cae..3d88805 100644 --- a/react/yarn.lock +++ b/react/yarn.lock @@ -2485,6 +2485,15 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== +axios@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^25.5.1: version "25.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.5.1.tgz#bc2e6101f849d6f6aec09720ffc7bc5332e62853" @@ -2841,7 +2850,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3330,6 +3339,11 @@ focus-visible@^5.2.0: resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.2.0.tgz#3a9e41fccf587bd25dcc2ef045508284f0a4d6b3" integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ== +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3340,6 +3354,15 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4935,6 +4958,11 @@ prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" From fc479f8faf47e531d45c8f69d354e7cff5de6bd3 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 13 Jul 2023 17:25:21 -0300 Subject: [PATCH 04/24] Rename fields style (from camelcase to snake case) because analytics queries extraction demand it --- react/utils/metrics.ts | 51 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index fed20c2..0fba6c6 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -29,24 +29,24 @@ type Metric = { } type QuoteFieldsMetric = { - orgId: string - costCenterId: string - costCenterName: string - buyOrgId: string - buyOrgName: string - memberId: string - memberEmail: string - memberName: string + org_id: string + cost_center_id: string + cost_center_name: string + buy_org_id: string + buy_org_name: string + member_id: string + member_email: string role: string - creationDate: string - quoteId: string - quoteReferenceName: string - sendToSalesRep: boolean + creation_date: string + quote_id: string + quote_reference_name: string + send_to_sales_rep: boolean } export type SessionProfile = { - id: string - email: string + id: { value: string } + email: { value: string } + firstName?: string lastName?: string } @@ -63,19 +63,18 @@ export const buildQuoteMetric = ( description: 'Create Quotation Action - UI', account: metricsParam.accountName, fields: { - orgId: metricsParam.userData?.orgId, - costCenterId: metricsParam.userData?.costId, - costCenterName: metricsParam.costCenterName, - buyOrgId: metricsParam.userData.orgId, - buyOrgName: metricsParam.buyOrgName, - memberId: metricsParam.sessionProfile?.id, - memberEmail: metricsParam.sessionProfile?.email, - memberName: `${metricsParam.sessionProfile.firstName} ${metricsParam.sessionProfile.lastName}`, + org_id: metricsParam.userData?.orgId, + cost_center_id: metricsParam.userData?.costId, + cost_center_name: metricsParam.costCenterName, + buy_org_id: metricsParam.userData.orgId, + buy_org_name: metricsParam.buyOrgName, + member_id: metricsParam.sessionProfile?.id?.value, + member_email: metricsParam.sessionProfile?.email.value, role: metricsParam.userData?.roleId, - creationDate: new Date().toISOString(), - quoteId: metricsParam.quoteId, - quoteReferenceName: metricsParam.quoteReferenceName, - sendToSalesRep, + creation_date: new Date().toISOString(), + quote_id: metricsParam.quoteId, + quote_reference_name: metricsParam.quoteReferenceName, + send_to_sales_rep: sendToSalesRep, }, } From 3d8e132fcc73f020de76e7ed78ce168689a0501c Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 14 Jul 2023 10:08:30 -0300 Subject: [PATCH 05/24] Limit type visibility --- react/utils/metrics.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 0fba6c6..08dfb93 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -2,7 +2,7 @@ import axios from 'axios' const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' -export type UserData = { +type UserData = { id: string canImpersonate: boolean orgId: string @@ -11,7 +11,7 @@ export type UserData = { roleId: string } -export type MetricsParam = { +type MetricsParam = { sessionProfile: SessionProfile accountName: string userData: UserData @@ -51,9 +51,9 @@ export type SessionProfile = { lastName?: string } -export type QuoteMetric = Metric & { fields: QuoteFieldsMetric } +type QuoteMetric = Metric & { fields: QuoteFieldsMetric } -export const buildQuoteMetric = ( +const buildQuoteMetric = ( sendToSalesRep: boolean, metricsParam: MetricsParam ): QuoteMetric => { From 4631ec3f9ad1782d59bbb63f64752b1ce25b566a Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 14 Jul 2023 10:52:50 -0300 Subject: [PATCH 06/24] Removing unused dependencies --- package.json | 7 -- yarn.lock | 296 +-------------------------------------------------- 2 files changed, 3 insertions(+), 300 deletions(-) diff --git a/package.json b/package.json index c2c2896..64f0813 100644 --- a/package.json +++ b/package.json @@ -21,13 +21,6 @@ "prettier --write" ] }, - "dependencies": { - "axios": "1.4.0", - "react": "^18.2.0", - "react-apollo": "^3.1.5", - "react-intl": "^6.4.4", - "@vtex/raccoon-next": "^0.5.0" - }, "devDependencies": { "@types/node": "12.12.21", "@vtex/prettier-config": "^0.3.1", diff --git a/yarn.lock b/yarn.lock index d0457c5..bf93c94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,55 +2,6 @@ # yarn lockfile v1 -"@apollo/react-common@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@apollo/react-common/-/react-common-3.1.4.tgz#ec13c985be23ea8e799c9ea18e696eccc97be345" - integrity sha512-X5Kyro73bthWSCBJUC5XYQqMnG0dLWuDZmVkzog9dynovhfiVCV4kPSdgSIkqnb++cwCzOVuQ4rDKVwo2XRzQA== - dependencies: - ts-invariant "^0.4.4" - tslib "^1.10.0" - -"@apollo/react-components@^3.1.5": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@apollo/react-components/-/react-components-3.1.5.tgz#040d2f35ce4947747efe16f76d59dcbd797ffdaf" - integrity sha512-c82VyUuE9VBnJB7bnX+3dmwpIPMhyjMwyoSLyQWPHxz8jK4ak30XszJtqFf4eC4hwvvLYa+Ou6X73Q8V8e2/jg== - dependencies: - "@apollo/react-common" "^3.1.4" - "@apollo/react-hooks" "^3.1.5" - prop-types "^15.7.2" - ts-invariant "^0.4.4" - tslib "^1.10.0" - -"@apollo/react-hoc@^3.1.5": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@apollo/react-hoc/-/react-hoc-3.1.5.tgz#6552d2fb4aafc59fdc8f4e353358b98b89cfab6f" - integrity sha512-jlZ2pvEnRevLa54H563BU0/xrYSgWQ72GksarxUzCHQW85nmn9wQln0kLBX7Ua7SBt9WgiuYQXQVechaaCulfQ== - dependencies: - "@apollo/react-common" "^3.1.4" - "@apollo/react-components" "^3.1.5" - hoist-non-react-statics "^3.3.0" - ts-invariant "^0.4.4" - tslib "^1.10.0" - -"@apollo/react-hooks@^3.1.5": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@apollo/react-hooks/-/react-hooks-3.1.5.tgz#7e710be52461255ae7fc0b3b9c2ece64299c10e6" - integrity sha512-y0CJ393DLxIIkksRup4nt+vSjxalbZBXnnXxYbviq/woj+zKa431zy0yT4LqyRKpFy9ahMIwxBnBwfwIoupqLQ== - dependencies: - "@apollo/react-common" "^3.1.4" - "@wry/equality" "^0.1.9" - ts-invariant "^0.4.4" - tslib "^1.10.0" - -"@apollo/react-ssr@^3.1.5": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@apollo/react-ssr/-/react-ssr-3.1.5.tgz#53703cd493afcde567acc6d5512cab03dafce6de" - integrity sha512-wuLPkKlctNn3u8EU8rlECyktpOUCeekFfb0KhIKknpGY6Lza2Qu0bThx7D9MIbVEzhKadNNrzLcpk0Y8/5UuWg== - dependencies: - "@apollo/react-common" "^3.1.4" - "@apollo/react-hooks" "^3.1.5" - tslib "^1.10.0" - "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -109,76 +60,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@formatjs/ecma402-abstract@1.17.0": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz#2ce191a3bde4c65c6684e03fa247062a4a294b9e" - integrity sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ== - dependencies: - "@formatjs/intl-localematcher" "0.4.0" - tslib "^2.4.0" - -"@formatjs/fast-memoize@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" - integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== - dependencies: - tslib "^2.4.0" - -"@formatjs/icu-messageformat-parser@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.0.tgz#b0d58ce8c8f472969c96b5cd0b3ad5522d3a02b7" - integrity sha512-yT6at0qc0DANw9qM/TU8RZaCtfDXtj4pZM/IC2WnVU80yAcliS3KVDiuUt4jSQAeFL9JS5bc2hARnFmjPdA6qw== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/icu-skeleton-parser" "1.6.0" - tslib "^2.4.0" - -"@formatjs/icu-skeleton-parser@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.0.tgz#0728be8b6b3656f1a4b8e6e5b0e02dffffc23c6c" - integrity sha512-eMmxNpoX/J1IPUjPGSZwo0Wh+7CEvdEMddP2Jxg1gQJXfGfht/FdW2D5XDFj3VMbOTUQlDIdZJY7uC6O6gjPoA== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - tslib "^2.4.0" - -"@formatjs/intl-displaynames@6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.5.0.tgz#32737088e7d943fb3e22140e64bb634e0ba05fcf" - integrity sha512-sg/nR8ILEdUl+2sWu6jc1nQ5s04yucGlH1RVfatW8TSJ5uG3Yy3vgigi8NNC/BuhcncUNPWqSpTCSI1hA+rhiw== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/intl-localematcher" "0.4.0" - tslib "^2.4.0" - -"@formatjs/intl-listformat@7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.0.tgz#fa8ac535d82fc716f052f2fd60eeaa7331362357" - integrity sha512-ifupb+balZUAF/Oh3QyGRqPRWGSKwWoMPR0cYZEG7r61SimD+m38oFQqVx/3Fp7LfQFF11m7IS+MlxOo2sKINA== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/intl-localematcher" "0.4.0" - tslib "^2.4.0" - -"@formatjs/intl-localematcher@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz#63bbc37a7c3545a1bf1686072e51d9a3aed98d6b" - integrity sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw== - dependencies: - tslib "^2.4.0" - -"@formatjs/intl@2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.9.0.tgz#e1335572af3ca8a53e136a78e866f1851a9718c2" - integrity sha512-Ym0trUoC/VO6wQu4YHa0H1VR2tEixFRmwZgADkDLm7nD+vv1Ob+/88mUAoT0pwvirFqYKgUKEwp1tFepqyqvVA== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/intl-displaynames" "6.5.0" - "@formatjs/intl-listformat" "7.4.0" - intl-messageformat "10.5.0" - tslib "^2.4.0" - "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -221,14 +102,6 @@ dependencies: any-observable "^0.3.0" -"@types/hoist-non-react-statics@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - "@types/json-schema@^7.0.7": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -249,25 +122,6 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/prop-types@*": - version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/react@*", "@types/react@16 || 17 || 18": - version "18.2.14" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127" - integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== - "@typescript-eslint/eslint-plugin@^4.14.1": version "4.32.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.32.0.tgz#46d2370ae9311092f2a6f7246d28357daf2d4e89" @@ -343,25 +197,6 @@ resolved "https://registry.yarnpkg.com/@vtex/prettier-config/-/prettier-config-0.3.6.tgz#31762608d9a59b815b6d4e963e439b12f1a12279" integrity sha512-nXE3BcMODomFK3EowfK+Hdj2qQRqB8JcdRv8yTREXnN9xq8DYKmH/dWB+RY/Hn3KozFLbygpZRbqYsiA6HDINQ== -"@vtex/raccoon-next@^0.5.0": - version "0.5.12" - resolved "https://registry.yarnpkg.com/@vtex/raccoon-next/-/raccoon-next-0.5.12.tgz#53f8674cf9dfdda59aed212b0ce8f370c99fa16f" - integrity sha512-pCyCon/QHbKB0lg8oWbdNK1cdWJQhAhzcaBQazi4+MCstT1fx23Gmv7BRIePtfZ6ovJWesEreripxBDssMzszw== - dependencies: - "@vtex/raccoon-shared-types" "^0.2.12" - -"@vtex/raccoon-shared-types@^0.2.12": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@vtex/raccoon-shared-types/-/raccoon-shared-types-0.2.12.tgz#29992bbb71c5c5842e965271e44394298ca2cdcc" - integrity sha512-vNgPRRH3O3vGziCJC+iY+nYSH10/5GYIC+UwVzfjWm3DT6w/GAh6WPgYXGzQpGeEhbDhPuYdeESR0eZrFt3FbQ== - -"@wry/equality@^0.1.9": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" - integrity sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA== - dependencies: - tslib "^1.9.3" - acorn-jsx@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -501,25 +336,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - axe-core@^4.0.2: version "4.3.3" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== -axios@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" - integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -643,13 +464,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - commander@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -695,11 +509,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - damerau-levenshtein@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" @@ -748,11 +557,6 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1229,20 +1033,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== -follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1381,13 +1171,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -1464,16 +1247,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -intl-messageformat@10.5.0: - version "10.5.0" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.0.tgz#86d11b15913ac954075b25253f5e669359f89538" - integrity sha512-AvojYuOaRb6r2veOKfTVpxH9TrmjSdc5iR9R5RgBwrDZYSmAAFVT+QLbW3C4V7Qsg0OguMp67Q/EoUkxZzXRGw== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.6.0" - tslib "^2.4.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -1822,7 +1595,7 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -1854,18 +1627,6 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -2213,11 +1974,6 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2236,45 +1992,11 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-apollo@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-3.1.5.tgz#36692d393c47e7ccc37f0a885c7cc5a8b4961c91" - integrity sha512-xOxMqxORps+WHrUYbjVHPliviomefOpu5Sh35oO3osuOyPTxvrljdfTLGCggMhcXBsDljtS5Oy4g+ijWg3D4JQ== - dependencies: - "@apollo/react-common" "^3.1.4" - "@apollo/react-components" "^3.1.5" - "@apollo/react-hoc" "^3.1.5" - "@apollo/react-hooks" "^3.1.5" - "@apollo/react-ssr" "^3.1.5" - -react-intl@^6.4.4: - version "6.4.4" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.4.4.tgz#14b45ce046bfbb60c0e6d392d8ddc30e9ead5a4f" - integrity sha512-/C9Sl/5//ohfkNG6AWlJuf4BhTXsbzyk93K62A4zRhSPANyOGpKZ+fWhN+TLfFd5YjDUHy+exU/09y0w1bO4Xw== - dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/intl" "2.9.0" - "@formatjs/intl-displaynames" "6.5.0" - "@formatjs/intl-listformat" "7.4.0" - "@types/hoist-non-react-statics" "^3.3.1" - "@types/react" "16 || 17 || 18" - hoist-non-react-statics "^3.3.2" - intl-messageformat "10.5.0" - tslib "^2.4.0" - -react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -2627,13 +2349,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -ts-invariant@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" - integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA== - dependencies: - tslib "^1.9.3" - tsconfig-paths@^3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" @@ -2644,16 +2359,11 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.4.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" - integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" From 17de4e2fdd48ec74198dda974471789ea38572a6 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 14 Jul 2023 11:47:07 -0300 Subject: [PATCH 07/24] Update readme.me with info about create quotation event --- docs/README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/README.md b/docs/README.md index 7f84c35..67b3dad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -251,6 +251,43 @@ Note that users with [storefront permissions](#storefront-permissions) to edit q ![app-configuration](https://user-images.githubusercontent.com/6306265/163218059-903cfbcf-0077-45d2-9457-19ee0ba4d5c8.png) +## **Metrics** +List of business metrics are sent do [Analytics Redshift](https://internal-docs.vtex.com/Analytics/VTEX-Data-Platform/data-ingestion-API/). + +Data are saved into `"vtex"."schemaless"."b2b_suite_buyerorg_data_raw"` with `payload.name = 'b2b-suite-buyerorg-data'`` + +**Quotation Created** + +Event sent every time a new quotation is created. + +Data Type: +``` +type Metric = { + name: 'b2b-suite-buyerorg-data' + kind: 'create-quote-ui-event' + description: 'Create Quotation Action - UI' + account: string +} + +type QuoteFieldsMetric = { + org_id: string + cost_center_id: string + cost_center_name: string + buy_org_id: string + buy_org_name: string + member_id: string + member_email: string + role: string + creation_date: string + quote_id: string + quote_reference_name: string + send_to_sales_rep: boolean +} + +type QuoteMetric = Metric & { fields: QuoteFieldsMetric } +``` +--- + ## Contributors ✨ From c4667b28adf2419c279257d9f94c350106dcd440 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 14 Jul 2023 11:50:04 -0300 Subject: [PATCH 08/24] Add changelog data --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4483015..5afd027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ++ ### Added ++ - Quotation created metrics sent to Analytics Redshift + ## [1.5.5] - 2023-06-29 ### Fixed From 8b3975132e473a243aba0bcb414a575a7f66c9db Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 14 Jul 2023 13:47:43 -0300 Subject: [PATCH 09/24] Removing internal data from external documentation --- docs/README.md | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/docs/README.md b/docs/README.md index 67b3dad..883c704 100644 --- a/docs/README.md +++ b/docs/README.md @@ -251,41 +251,6 @@ Note that users with [storefront permissions](#storefront-permissions) to edit q ![app-configuration](https://user-images.githubusercontent.com/6306265/163218059-903cfbcf-0077-45d2-9457-19ee0ba4d5c8.png) -## **Metrics** -List of business metrics are sent do [Analytics Redshift](https://internal-docs.vtex.com/Analytics/VTEX-Data-Platform/data-ingestion-API/). - -Data are saved into `"vtex"."schemaless"."b2b_suite_buyerorg_data_raw"` with `payload.name = 'b2b-suite-buyerorg-data'`` - -**Quotation Created** - -Event sent every time a new quotation is created. - -Data Type: -``` -type Metric = { - name: 'b2b-suite-buyerorg-data' - kind: 'create-quote-ui-event' - description: 'Create Quotation Action - UI' - account: string -} - -type QuoteFieldsMetric = { - org_id: string - cost_center_id: string - cost_center_name: string - buy_org_id: string - buy_org_name: string - member_id: string - member_email: string - role: string - creation_date: string - quote_id: string - quote_reference_name: string - send_to_sales_rep: boolean -} - -type QuoteMetric = Metric & { fields: QuoteFieldsMetric } -``` --- From 299b5e7184088b838b8891e392554d3f45e65b5b Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Mon, 17 Jul 2023 09:08:24 -0300 Subject: [PATCH 10/24] Reverting Readme --- docs/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 883c704..7f84c35 100644 --- a/docs/README.md +++ b/docs/README.md @@ -251,8 +251,6 @@ Note that users with [storefront permissions](#storefront-permissions) to edit q ![app-configuration](https://user-images.githubusercontent.com/6306265/163218059-903cfbcf-0077-45d2-9457-19ee0ba4d5c8.png) ---- - ## Contributors ✨ From 0d2b784c8fbe0d3ef7325e96edfd8155a56268d5 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Mon, 17 Jul 2023 18:29:24 -0300 Subject: [PATCH 11/24] Reduzing graphql calls --- .../components/QuoteDetails/QuoteDetails.tsx | 33 +---- react/utils/metrics.ts | 133 ++++++++++++------ 2 files changed, 98 insertions(+), 68 deletions(-) diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index 70187ed..34dea54 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -29,9 +29,6 @@ import UPDATE_QUOTE from '../../graphql/updateQuote.graphql' import USE_QUOTE from '../../graphql/useQuote.graphql' import GET_AUTH_RULES from '../../graphql/getDimension.graphql' import CLEAR_CART from '../../graphql/clearCartMutation.graphql' -import CHECK_PERMISSIONS from '../../graphql/checkPermissions.graphql' -import GET_COSTCENTER_BY_ID from '../../graphql/getCostCenter.graphql' -import GET_ORGANIZATION_BY_ID from '../../graphql/getOrganization.graphql' import storageFactory from '../../utils/storage' import PercentageDiscount from './PercentageDiscount' import QuoteName from './QuoteName' @@ -41,7 +38,6 @@ import AlertMessage from './AlertMessage' import QuoteTable from './QuoteTable' import QuoteUpdateHistory from './QuoteUpdateHistory' import { Status } from '../../utils/status' -import type { SessionProfile } from '../../utils/metrics' import { sendMetric } from '../../utils/metrics' const localStore = storageFactory(() => localStorage) @@ -77,6 +73,7 @@ const QuoteDetails: FunctionComponent = () => { const { route: { params }, navigate, + workspace, } = useRuntime() const isNewQuote = !params?.id @@ -117,21 +114,6 @@ const QuoteDetails: FunctionComponent = () => { /** * GraphQL Queries */ - const userEmail = sessionResponse?.namespaces?.profile?.email?.value - const { data: userData } = useQuery(CHECK_PERMISSIONS, { - variables: { email: userEmail }, - }) - - const costCenterId: string = userData?.getUserByEmail?.[0]?.costId - const { data: costCenterData } = useQuery(GET_COSTCENTER_BY_ID, { - variables: { id: costCenterId }, - }) - - const orgId: string = userData?.getUserByEmail?.[0]?.orgId - const { data: organizationData } = useQuery(GET_ORGANIZATION_BY_ID, { - variables: { id: orgId }, - }) - const { data, loading, refetch } = useQuery(GET_QUOTE, { variables: { id: params?.id }, ssr: false, @@ -217,18 +199,13 @@ const QuoteDetails: FunctionComponent = () => { .then((result: any) => { if (result.data.createQuote) { const metricsParam = { - sessionProfile: sessionResponse?.namespaces - ?.profile as SessionProfile, - accountName: sessionResponse?.namespaces?.account?.accountName - ?.value as string, - userData: userData?.getUserByEmail?.[0], - costCenterName: costCenterData?.getCostCenterById?.name, - buyOrgName: organizationData?.getOrganizationById?.name, quoteId: result.data.createQuote, - quoteReferenceName: quoteState.referenceName, + sessionResponse, + workspace, + sendToSalesRep, } - sendMetric(sendToSalesRep, metricsParam) + sendMetric(metricsParam) toastMessage(quoteMessages.createSuccess) handleClearCart(orderForm.orderFormId).then(() => { diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 08dfb93..1ea7f5e 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -2,23 +2,12 @@ import axios from 'axios' const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' -type UserData = { - id: string - canImpersonate: boolean - orgId: string - clId: string - costId: string - roleId: string -} +const GRAPHQL_URL = (accountName: string, workspace?: string) => { + if (workspace) { + return `https://${workspace}--${accountName}.myvtex.com/_v/private/graphql/v1` + } -type MetricsParam = { - sessionProfile: SessionProfile - accountName: string - userData: UserData - costCenterName: string - buyOrgName: string - quoteId: string - quoteReferenceName: string + return `https://${accountName}.myvtex.com/_v/private/graphql/v1` } type Metric = { @@ -29,7 +18,6 @@ type Metric = { } type QuoteFieldsMetric = { - org_id: string cost_center_id: string cost_center_name: string buy_org_id: string @@ -46,50 +34,115 @@ type QuoteFieldsMetric = { export type SessionProfile = { id: { value: string } email: { value: string } +} - firstName?: string - lastName?: string +type SessionResponse = { + namespaces: { + profile: SessionProfile + account: { + accountName: { value: string } + } + } +} + +type MetricsParam = { + quoteId: string + sessionResponse: SessionResponse + workspace: string + sendToSalesRep: boolean } type QuoteMetric = Metric & { fields: QuoteFieldsMetric } -const buildQuoteMetric = ( - sendToSalesRep: boolean, +const fetchMetricsData = async ( + accountName: string, + workspace: string, + quoteId: string, + userEmail: string +) => { + const query = JSON.stringify({ + query: `query GetMetricsData($id: String, $email: String!) { + getQuote(id: $id) @context(provider: "vtex.b2b-quotes-graphql") { + organization + organizationName + costCenterName + referenceName + creatorRole + creationDate + }, + getUserByEmail(email: $email) @context(provider: "vtex.storefront-permissions") { + costId + } + }`, + variables: { id: quoteId, email: userEmail }, + }) + + const { data } = ( + await axios.post(GRAPHQL_URL(accountName, workspace), query) + ).data + + const quoteResult = data.getQuote as Omit + const costId = data.getUserByEmail?.[0].costId as string + + return { + ...quoteResult, + costId, + } +} + +const buildQuoteMetric = async ( metricsParam: MetricsParam -): QuoteMetric => { +): Promise => { + const { namespaces } = metricsParam.sessionResponse + const accountName = namespaces.account.accountName.value + const userEmail = namespaces.profile.email.value + + const metricsData = await fetchMetricsData( + accountName, + metricsParam.workspace, + metricsParam.quoteId, + userEmail + ) + const metric: QuoteMetric = { name: 'b2b-suite-buyerorg-data', kind: 'create-quote-ui-event', description: 'Create Quotation Action - UI', - account: metricsParam.accountName, + account: accountName, fields: { - org_id: metricsParam.userData?.orgId, - cost_center_id: metricsParam.userData?.costId, - cost_center_name: metricsParam.costCenterName, - buy_org_id: metricsParam.userData.orgId, - buy_org_name: metricsParam.buyOrgName, - member_id: metricsParam.sessionProfile?.id?.value, - member_email: metricsParam.sessionProfile?.email.value, - role: metricsParam.userData?.roleId, - creation_date: new Date().toISOString(), + buy_org_id: metricsData.organization, + buy_org_name: metricsData.organizationName, + cost_center_id: metricsData.costId, + cost_center_name: metricsData.costCenterName, + member_id: namespaces?.profile?.id?.value, + member_email: userEmail, + role: metricsData.creatorRole, + creation_date: metricsData.creationDate, quote_id: metricsParam.quoteId, - quote_reference_name: metricsParam.quoteReferenceName, - send_to_sales_rep: sendToSalesRep, + quote_reference_name: metricsData.referenceName, + send_to_sales_rep: metricsParam.sendToSalesRep, }, } return metric } -export const sendMetric = async ( - sendToSalesRep: boolean, - metricsParam: MetricsParam -) => { +type QuoteMetricsData = { + organization: string // organizationId + organizationName: string + costId: string + costCenterName: string + referenceName: string // quote reference name + creatorRole: string + creationDate: string +} + +export const sendMetric = async (metricsParam: MetricsParam) => { try { - const metric = buildQuoteMetric(sendToSalesRep, metricsParam) + const metric = await buildQuoteMetric(metricsParam) axios.post(ANALYTICS_URL, metric) } catch (error) { - console.error('Unable to log metrics', error) + console.warn('Unable to log metrics', error) } } From fc5dc223e9811c489ac9fcf56e69bfaf2e4fc2c5 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Tue, 18 Jul 2023 09:21:43 -0300 Subject: [PATCH 12/24] Await axios call --- react/utils/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 1ea7f5e..27075df 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -141,7 +141,7 @@ export const sendMetric = async (metricsParam: MetricsParam) => { try { const metric = await buildQuoteMetric(metricsParam) - axios.post(ANALYTICS_URL, metric) + await axios.post(ANALYTICS_URL, metric) } catch (error) { console.warn('Unable to log metrics', error) } From 2f5558d7c3b31b682651bdc220c733cfe22e38ea Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Wed, 19 Jul 2023 11:02:41 -0300 Subject: [PATCH 13/24] Get account from runtime instead of session and heck user null fields --- react/components/QuoteDetails/QuoteDetails.tsx | 2 ++ react/utils/metrics.ts | 13 +++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index 34dea54..19e1bbe 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -74,6 +74,7 @@ const QuoteDetails: FunctionComponent = () => { route: { params }, navigate, workspace, + account, } = useRuntime() const isNewQuote = !params?.id @@ -203,6 +204,7 @@ const QuoteDetails: FunctionComponent = () => { sessionResponse, workspace, sendToSalesRep, + account, } sendMetric(metricsParam) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 27075df..258ad5a 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -39,9 +39,6 @@ export type SessionProfile = { type SessionResponse = { namespaces: { profile: SessionProfile - account: { - accountName: { value: string } - } } } @@ -49,6 +46,7 @@ type MetricsParam = { quoteId: string sessionResponse: SessionResponse workspace: string + account: string sendToSalesRep: boolean } @@ -71,7 +69,7 @@ const fetchMetricsData = async ( creationDate }, getUserByEmail(email: $email) @context(provider: "vtex.storefront-permissions") { - costId + costId } }`, variables: { id: quoteId, email: userEmail }, @@ -94,11 +92,10 @@ const buildQuoteMetric = async ( metricsParam: MetricsParam ): Promise => { const { namespaces } = metricsParam.sessionResponse - const accountName = namespaces.account.accountName.value - const userEmail = namespaces.profile.email.value + const userEmail = namespaces?.profile?.email?.value const metricsData = await fetchMetricsData( - accountName, + metricsParam.account, metricsParam.workspace, metricsParam.quoteId, userEmail @@ -108,7 +105,7 @@ const buildQuoteMetric = async ( name: 'b2b-suite-buyerorg-data', kind: 'create-quote-ui-event', description: 'Create Quotation Action - UI', - account: accountName, + account: metricsParam.workspace, fields: { buy_org_id: metricsData.organization, buy_org_name: metricsData.organizationName, From b5201e288687c218dcdbd9b99d673a6b2fcdc5bd Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Wed, 19 Jul 2023 12:21:19 -0300 Subject: [PATCH 14/24] Fix accountName parameter --- react/utils/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 258ad5a..dd2c75b 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -105,7 +105,7 @@ const buildQuoteMetric = async ( name: 'b2b-suite-buyerorg-data', kind: 'create-quote-ui-event', description: 'Create Quotation Action - UI', - account: metricsParam.workspace, + account: metricsParam.account, fields: { buy_org_id: metricsData.organization, buy_org_name: metricsData.organizationName, From 9928cf8bbd06f0db29532296652d76ac378cafec Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 20 Jul 2023 10:35:39 -0300 Subject: [PATCH 15/24] Handle graphql errors --- react/utils/metrics.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index dd2c75b..75766af 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -75,12 +75,17 @@ const fetchMetricsData = async ( variables: { id: quoteId, email: userEmail }, }) - const { data } = ( + const { data, errors } = ( await axios.post(GRAPHQL_URL(accountName, workspace), query) ).data - const quoteResult = data.getQuote as Omit - const costId = data.getUserByEmail?.[0].costId as string + if (errors) { + console.error('Graphql errors', errors) + throw new Error('Graphql Errors when trying get quote and user data') + } + + const quoteResult = data?.getQuote as Omit + const costId = data?.getUserByEmail?.[0].costId as string return { ...quoteResult, From f1b4c409124768da1d5676dcd67af8e269b1f797 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 20 Jul 2023 11:00:29 -0300 Subject: [PATCH 16/24] Handle null string at costcenter --- react/utils/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/utils/metrics.ts b/react/utils/metrics.ts index 75766af..2a87d6d 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics.ts @@ -85,7 +85,7 @@ const fetchMetricsData = async ( } const quoteResult = data?.getQuote as Omit - const costId = data?.getUserByEmail?.[0].costId as string + const costId = (data?.getUserByEmail?.[0].costId ?? '') as string return { ...quoteResult, From 6a64cf5b9a422c92296603fa7c28de3a93ee5ed2 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Fri, 21 Jul 2023 21:57:24 -0300 Subject: [PATCH 17/24] Add Use Quote Metrics --- .../components/QuoteDetails/QuoteDetails.tsx | 14 +++- .../{metrics.ts => metrics/createQuote.ts} | 43 ++++-------- react/utils/metrics/metrics.ts | 37 +++++++++++ react/utils/metrics/useQuote.ts | 65 +++++++++++++++++++ 4 files changed, 128 insertions(+), 31 deletions(-) rename react/utils/{metrics.ts => metrics/createQuote.ts} (79%) create mode 100644 react/utils/metrics/metrics.ts create mode 100644 react/utils/metrics/useQuote.ts diff --git a/react/components/QuoteDetails/QuoteDetails.tsx b/react/components/QuoteDetails/QuoteDetails.tsx index 19e1bbe..6432083 100644 --- a/react/components/QuoteDetails/QuoteDetails.tsx +++ b/react/components/QuoteDetails/QuoteDetails.tsx @@ -38,7 +38,9 @@ import AlertMessage from './AlertMessage' import QuoteTable from './QuoteTable' import QuoteUpdateHistory from './QuoteUpdateHistory' import { Status } from '../../utils/status' -import { sendMetric } from '../../utils/metrics' +import { sendCreateQuoteMetric } from '../../utils/metrics/createQuote' +import type { UseQuoteMetricsParams } from '../../utils/metrics/useQuote' +import { sendUseQuoteMetric } from '../../utils/metrics/useQuote' const localStore = storageFactory(() => localStorage) const MAX_DISCOUNT_PERCENTAGE = 99 @@ -207,7 +209,7 @@ const QuoteDetails: FunctionComponent = () => { account, } - sendMetric(metricsParam) + sendCreateQuoteMetric(metricsParam) toastMessage(quoteMessages.createSuccess) handleClearCart(orderForm.orderFormId).then(() => { @@ -305,6 +307,14 @@ const QuoteDetails: FunctionComponent = () => { setUsingQuoteState(false) }) .then(() => { + const metricsParam: UseQuoteMetricsParams = { + quoteState, + orderFormId: variables.orderFormId, + account, + sessionResponse, + } + + sendUseQuoteMetric(metricsParam) goToCheckout(checkoutUrl) setUsingQuoteState(false) }) diff --git a/react/utils/metrics.ts b/react/utils/metrics/createQuote.ts similarity index 79% rename from react/utils/metrics.ts rename to react/utils/metrics/createQuote.ts index 2a87d6d..1db55fe 100644 --- a/react/utils/metrics.ts +++ b/react/utils/metrics/createQuote.ts @@ -1,6 +1,7 @@ import axios from 'axios' -const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' +import type { Metric, SessionResponse } from './metrics' +import { sendMetric } from './metrics' const GRAPHQL_URL = (accountName: string, workspace?: string) => { if (workspace) { @@ -10,14 +11,7 @@ const GRAPHQL_URL = (accountName: string, workspace?: string) => { return `https://${accountName}.myvtex.com/_v/private/graphql/v1` } -type Metric = { - name: 'b2b-suite-buyerorg-data' - kind: 'create-quote-ui-event' - description: 'Create Quotation Action - UI' - account: string -} - -type QuoteFieldsMetric = { +type CreateQuoteFieldsMetric = { cost_center_id: string cost_center_name: string buy_org_id: string @@ -31,18 +25,7 @@ type QuoteFieldsMetric = { send_to_sales_rep: boolean } -export type SessionProfile = { - id: { value: string } - email: { value: string } -} - -type SessionResponse = { - namespaces: { - profile: SessionProfile - } -} - -type MetricsParam = { +type CreateQuoteMetricsParam = { quoteId: string sessionResponse: SessionResponse workspace: string @@ -50,7 +33,7 @@ type MetricsParam = { sendToSalesRep: boolean } -type QuoteMetric = Metric & { fields: QuoteFieldsMetric } +type CreateQuoteMetric = Metric & { fields: CreateQuoteFieldsMetric } const fetchMetricsData = async ( accountName: string, @@ -93,9 +76,9 @@ const fetchMetricsData = async ( } } -const buildQuoteMetric = async ( - metricsParam: MetricsParam -): Promise => { +const buildCreateQuoteMetric = async ( + metricsParam: CreateQuoteMetricsParam +): Promise => { const { namespaces } = metricsParam.sessionResponse const userEmail = namespaces?.profile?.email?.value @@ -106,7 +89,7 @@ const buildQuoteMetric = async ( userEmail ) - const metric: QuoteMetric = { + const metric: CreateQuoteMetric = { name: 'b2b-suite-buyerorg-data', kind: 'create-quote-ui-event', description: 'Create Quotation Action - UI', @@ -139,11 +122,13 @@ type QuoteMetricsData = { creationDate: string } -export const sendMetric = async (metricsParam: MetricsParam) => { +export const sendCreateQuoteMetric = async ( + metricsParam: CreateQuoteMetricsParam +) => { try { - const metric = await buildQuoteMetric(metricsParam) + const metric = await buildCreateQuoteMetric(metricsParam) - await axios.post(ANALYTICS_URL, metric) + await sendMetric(metric) } catch (error) { console.warn('Unable to log metrics', error) } diff --git a/react/utils/metrics/metrics.ts b/react/utils/metrics/metrics.ts new file mode 100644 index 0000000..8bc530b --- /dev/null +++ b/react/utils/metrics/metrics.ts @@ -0,0 +1,37 @@ +import axios from 'axios' + +const ANALYTICS_URL = 'https://rc.vtex.com/api/analytics/schemaless-events' + +type CreateQuoteMetric = { + kind: 'create-quote-ui-event' + description: 'Create Quotation Action - UI' +} + +type UseQuoteMetric = { + kind: 'use-quote-ui-event' + description: 'Use Quotation Action - UI' +} + +export type Metric = { + name: 'b2b-suite-buyerorg-data' + account: string +} & (CreateQuoteMetric | UseQuoteMetric) + +export type SessionProfile = { + id: { value: string } + email: { value: string } +} + +export type SessionResponse = { + namespaces: { + profile: SessionProfile + } +} + +export const sendMetric = async (metric: Metric) => { + try { + await axios.post(ANALYTICS_URL, metric) + } catch (error) { + console.warn('Unable to log metrics', error) + } +} diff --git a/react/utils/metrics/useQuote.ts b/react/utils/metrics/useQuote.ts new file mode 100644 index 0000000..de94ca4 --- /dev/null +++ b/react/utils/metrics/useQuote.ts @@ -0,0 +1,65 @@ +import type { Metric, SessionResponse } from './metrics' +import { sendMetric } from './metrics' + +type UseQuoteFieldsMetric = { + quote_id: string + quote_reference_name: string + order_form_id: string + quote_creation_date: string + quote_use_date: string + creator_email: string + user_email: string + cost_center_name: string + buy_org_id: string + buy_org_name: string + quote_last_update: string +} + +type UseQuoteMetric = Metric & { fields: UseQuoteFieldsMetric } + +export type UseQuoteMetricsParams = { + quoteState: Quote + orderFormId: string + account: string + sessionResponse: SessionResponse +} + +const buildUseQuoteMetric = async ( + metricsParam: UseQuoteMetricsParams +): Promise => { + const { quoteState, orderFormId, account, sessionResponse } = metricsParam + + const metric: UseQuoteMetric = { + name: 'b2b-suite-buyerorg-data', + kind: 'use-quote-ui-event', + description: 'Use Quotation Action - UI', + account, + fields: { + buy_org_id: quoteState.organization, + buy_org_name: quoteState.organizationName, + cost_center_name: quoteState.costCenterName, + quote_id: quoteState.id, + quote_reference_name: quoteState.referenceName, + order_form_id: orderFormId, + quote_creation_date: quoteState.creationDate, + quote_use_date: new Date().toISOString(), + creator_email: quoteState.creatorEmail, + user_email: sessionResponse.namespaces?.profile?.email?.value, + quote_last_update: quoteState.lastUpdate, + }, + } + + return metric +} + +export const sendUseQuoteMetric = async ( + metricsParam: UseQuoteMetricsParams +) => { + try { + const metric = await buildUseQuoteMetric(metricsParam) + + sendMetric(metric) + } catch (error) { + console.warn('Unable to log metrics', error) + } +} From dd752605b467951745bd6426e1a28755c74a5137 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Mon, 24 Jul 2023 09:00:57 -0300 Subject: [PATCH 18/24] Add change to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5afd027..211c6ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + ### Added + - Quotation created metrics sent to Analytics Redshift ++ - Use quote metrics sent to Analytics Redshift ## [1.5.5] - 2023-06-29 From 4f5771e864fbd1699dfb434f942e002298b89d8a Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Wed, 26 Jul 2023 10:58:41 -0300 Subject: [PATCH 19/24] Handle async in methods --- react/utils/metrics/useQuote.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/react/utils/metrics/useQuote.ts b/react/utils/metrics/useQuote.ts index de94ca4..9b89e85 100644 --- a/react/utils/metrics/useQuote.ts +++ b/react/utils/metrics/useQuote.ts @@ -24,9 +24,9 @@ export type UseQuoteMetricsParams = { sessionResponse: SessionResponse } -const buildUseQuoteMetric = async ( +const buildUseQuoteMetric = ( metricsParam: UseQuoteMetricsParams -): Promise => { +): UseQuoteMetric => { const { quoteState, orderFormId, account, sessionResponse } = metricsParam const metric: UseQuoteMetric = { @@ -56,9 +56,9 @@ export const sendUseQuoteMetric = async ( metricsParam: UseQuoteMetricsParams ) => { try { - const metric = await buildUseQuoteMetric(metricsParam) + const metric = buildUseQuoteMetric(metricsParam) - sendMetric(metric) + await sendMetric(metric) } catch (error) { console.warn('Unable to log metrics', error) } From 65b826c1577c17d88bc2a17a52a1b931de4e1ca4 Mon Sep 17 00:00:00 2001 From: mtakeda <1576737+mtakeda@users.noreply.github.com> Date: Thu, 3 Aug 2023 02:59:58 +0000 Subject: [PATCH 20/24] Release v1.5.6 --- CHANGELOG.md | 2 ++ manifest.json | 2 +- react/package.json | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 211c6ec..5c83b59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.5.6] - 2023-08-03 + + ### Added + - Quotation created metrics sent to Analytics Redshift + - Use quote metrics sent to Analytics Redshift diff --git a/manifest.json b/manifest.json index 7f0c5ac..0c83398 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "vendor": "vtex", "name": "b2b-quotes", - "version": "1.5.5", + "version": "1.5.6", "title": "B2B Quotes & Carts", "description": "Allows B2B Customers to request quotes from their sales reps and/or save carts for future use", "builders": { diff --git a/react/package.json b/react/package.json index fe179b9..1dd008c 100644 --- a/react/package.json +++ b/react/package.json @@ -1,6 +1,6 @@ { "name": "vtex.b2b-quotes", - "version": "1.5.5", + "version": "1.5.6", "scripts": { "test": "vtex-test-tools test" }, From bd5734c5b0b4e169e542c17e608d566e0ea970d0 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 3 Aug 2023 01:44:07 -0300 Subject: [PATCH 21/24] Changelog --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c83b59..211c6ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [1.5.6] - 2023-08-03 - + ### Added + - Quotation created metrics sent to Analytics Redshift + - Use quote metrics sent to Analytics Redshift From 539210235ffb74c439e82af4d0fbd80e2d7a164d Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 3 Aug 2023 09:02:50 -0300 Subject: [PATCH 22/24] Revert bump version in manifest --- manifest.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/manifest.json b/manifest.json index 0c83398..061e427 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "vendor": "vtex", "name": "b2b-quotes", - "version": "1.5.6", + "version": "1.5.5", "title": "B2B Quotes & Carts", "description": "Allows B2B Customers to request quotes from their sales reps and/or save carts for future use", "builders": { @@ -29,9 +29,7 @@ "vtex.my-account": "1.x", "vtex.my-account-commons": "1.x" }, - "registries": [ - "smartcheckout" - ], + "registries": ["smartcheckout"], "policies": [], "$schema": "https://raw.githubusercontent.com/vtex/node-vtex-api/master/gen/manifest.schema" } From bf68d1cbc2f8e3350a06b99e1beb8c8c59138da9 Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 3 Aug 2023 09:03:32 -0300 Subject: [PATCH 23/24] Revert bump version in package --- react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/package.json b/react/package.json index 1dd008c..fe179b9 100644 --- a/react/package.json +++ b/react/package.json @@ -1,6 +1,6 @@ { "name": "vtex.b2b-quotes", - "version": "1.5.6", + "version": "1.5.5", "scripts": { "test": "vtex-test-tools test" }, From 4bff5c207d5dca5c04fd88a93285e8ec5525f8dd Mon Sep 17 00:00:00 2001 From: Mauro Takeda Date: Thu, 3 Aug 2023 09:05:02 -0300 Subject: [PATCH 24/24] Fix typo --- react/utils/metrics/createQuote.ts | 8 ++++---- react/utils/metrics/useQuote.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/react/utils/metrics/createQuote.ts b/react/utils/metrics/createQuote.ts index 1db55fe..c5ee173 100644 --- a/react/utils/metrics/createQuote.ts +++ b/react/utils/metrics/createQuote.ts @@ -14,8 +14,8 @@ const GRAPHQL_URL = (accountName: string, workspace?: string) => { type CreateQuoteFieldsMetric = { cost_center_id: string cost_center_name: string - buy_org_id: string - buy_org_name: string + buyer_org_id: string + buyer_org_name: string member_id: string member_email: string role: string @@ -95,8 +95,8 @@ const buildCreateQuoteMetric = async ( description: 'Create Quotation Action - UI', account: metricsParam.account, fields: { - buy_org_id: metricsData.organization, - buy_org_name: metricsData.organizationName, + buyer_org_id: metricsData.organization, + buyer_org_name: metricsData.organizationName, cost_center_id: metricsData.costId, cost_center_name: metricsData.costCenterName, member_id: namespaces?.profile?.id?.value, diff --git a/react/utils/metrics/useQuote.ts b/react/utils/metrics/useQuote.ts index 9b89e85..404f4db 100644 --- a/react/utils/metrics/useQuote.ts +++ b/react/utils/metrics/useQuote.ts @@ -10,8 +10,8 @@ type UseQuoteFieldsMetric = { creator_email: string user_email: string cost_center_name: string - buy_org_id: string - buy_org_name: string + buyer_org_id: string + buyer_org_name: string quote_last_update: string } @@ -35,8 +35,8 @@ const buildUseQuoteMetric = ( description: 'Use Quotation Action - UI', account, fields: { - buy_org_id: quoteState.organization, - buy_org_name: quoteState.organizationName, + buyer_org_id: quoteState.organization, + buyer_org_name: quoteState.organizationName, cost_center_name: quoteState.costCenterName, quote_id: quoteState.id, quote_reference_name: quoteState.referenceName,