@bunnyapp/components 1.8.0-beta.13 → 1.8.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -1219,6 +1219,11 @@ const QueryKeyFactory = {
1219
1219
  entityId,
1220
1220
  ...(token ? [token] : []),
1221
1221
  ],
1222
+ quotesKey: (filter, token) => [
1223
+ 'quotes',
1224
+ ...(filter ? [filter] : []),
1225
+ ...(token ? [token] : []),
1226
+ ],
1222
1227
  createFormattedInvoiceKey: ({ id, token }) => [
1223
1228
  'formattedInvoice',
1224
1229
  id,
@@ -1283,7 +1288,7 @@ const DEFAULT_CONFIG = {
1283
1288
  };
1284
1289
 
1285
1290
  // This will be replaced at build time by rollup-plugin-replace
1286
- const PACKAGE_VERSION = '1.8.0-beta.12';
1291
+ const PACKAGE_VERSION = '1.8.0-beta.14';
1287
1292
  const createRequestHeaders = (token) => {
1288
1293
  const headers = createClientDevHeaders({ token });
1289
1294
  // Add the components version header
@@ -22165,6 +22170,7 @@ const QuoteButtons_FormattedQuoteFragment = t(`
22165
22170
  currency
22166
22171
  amount
22167
22172
  expiresAt
22173
+ state
22168
22174
  }
22169
22175
  `);
22170
22176
  const PaymentHoldDisplay_QuoteButtonsFragment = t(`
@@ -22181,10 +22187,11 @@ function QuoteButtons({ isAccepted, formattedQuote: maskedFormattedQuote, isMobi
22181
22187
  const { secondaryColor } = useBrand();
22182
22188
  const downloadFile = useDownloadFile(id);
22183
22189
  const isExpired = useIsExpired(formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.expiresAt);
22190
+ const isRejected = (formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.state) === 'REJECTED';
22184
22191
  const signingPlugins = useSigningPlugins({ apiHost, token });
22185
22192
  return (jsxRuntime.jsxs("div", { className: "flex flex-row justify-end items-center gap-4", id: "acceptance", style: {
22186
22193
  color: secondaryColor,
22187
- }, children: [isAccepted && formattedQuote.acceptedAt ? (jsxRuntime.jsx(Text$y, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxRuntime.jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsxRuntime.jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsxRuntime.jsx(antd.Button, { icon: jsxRuntime.jsx(icons.DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsxRuntime.jsx(antd.Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: !isAccepted ? (jsxRuntime.jsx(antd.Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
22194
+ }, children: [isAccepted && formattedQuote.acceptedAt ? (jsxRuntime.jsx(Text$y, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxRuntime.jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsxRuntime.jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsxRuntime.jsx(antd.Button, { icon: jsxRuntime.jsx(icons.DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsxRuntime.jsx(antd.Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: !isAccepted && !isRejected ? (jsxRuntime.jsx(antd.Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
22188
22195
  ? 'Quote is expired'
22189
22196
  : (signingPlugins === null || signingPlugins === void 0 ? void 0 : signingPlugins.length)
22190
22197
  ? 'Start signing'
@@ -22984,7 +22991,7 @@ function TransactionsDisplay({ transactions, onSearchValueChanged, search, }) {
22984
22991
  onTransactionDisplayClose === null || onTransactionDisplayClose === void 0 ? void 0 : onTransactionDisplayClose(selectedTransaction);
22985
22992
  setDrawerOpen(false);
22986
22993
  }
22987
- return (jsxRuntime.jsxs("div", { style: style, children: [jsxRuntime.jsxs("div", { className: `bunny-flex bunny-flex-col bunny-w-full bunny-shadow-padding-xb bunny-gap-2 ${isMobile ? 'bunny-overflow-hidden' : ''} ${className}`, children: [showTitle || showSearchBar ? (jsxRuntime.jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-col bunny-gap-1' : 'bunny-flex-row bunny-items-center'} bunny-justify-between`, children: [showTitle ? (jsxRuntime.jsx(Text$s, { className: "bunny-shrink-0 bunny-font-medium", style: { color: darkMode ? undefined : secondaryColor }, children: title })) : (jsxRuntime.jsx("div", {}) // Empty div so justify-between works
22994
+ return (jsxRuntime.jsxs("div", { style: style, children: [jsxRuntime.jsxs("div", { className: `bunny-flex bunny-flex-col bunny-w-full bunny-gap-2 ${isMobile ? 'bunny-overflow-hidden' : ''} ${className}`, children: [showTitle || showSearchBar ? (jsxRuntime.jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-col bunny-gap-1' : 'bunny-flex-row bunny-items-center'} bunny-justify-between`, children: [showTitle ? (jsxRuntime.jsx(Text$s, { className: "bunny-shrink-0 bunny-font-medium", style: { color: darkMode ? undefined : secondaryColor }, children: title })) : (jsxRuntime.jsx("div", {}) // Empty div so justify-between works
22988
22995
  ), showSearchBar && (jsxRuntime.jsx("div", { className: `${isMobile ? 'bunny-w-full' : ''}`, children: jsxRuntime.jsx(antd.Input, { className: searchBarClassName ? searchBarClassName : '', onChange: e => {
22989
22996
  const value = e.target.value;
22990
22997
  // Allow empty string, numbers, and decimal point
@@ -23002,6 +23009,7 @@ function TransactionsDisplay({ transactions, onSearchValueChanged, search, }) {
23002
23009
 
23003
23010
  function Quotes({ className, columns = ['date', 'title', 'amount', 'download', 'state'], filter, filterQuotes, sort = (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(), noQuotesMessage = 'There are no quotes', onQuoteClick, renderQuote, searchBarClassName, shadow = 'shadow-md', showSearchBar = true, showTitle = true, title = 'Past quotes', style, suppressQuoteDisplay = false, useModal = false, }) {
23004
23011
  const { apiHost } = react.useContext(BunnyContext);
23012
+ const queryClient = reactQuery.useQueryClient();
23005
23013
  const [component, setComponent] = react.useState(null);
23006
23014
  const contextValues = {
23007
23015
  columns,
@@ -23054,7 +23062,9 @@ function Quotes({ className, columns = ['date', 'title', 'amount', 'download', '
23054
23062
  setComponent(renderQuote(quote));
23055
23063
  }
23056
23064
  else {
23057
- setComponent(jsxRuntime.jsx(Quote, { id: quote === null || quote === void 0 ? void 0 : quote.transactionableId }));
23065
+ setComponent(jsxRuntime.jsx(Quote, { id: quote === null || quote === void 0 ? void 0 : quote.transactionableId, onQuoteAccepted: () => {
23066
+ queryClient.invalidateQueries({ queryKey: QueryKeyFactory.quotesKey() });
23067
+ } }));
23058
23068
  }
23059
23069
  }
23060
23070
  return (jsxRuntime.jsx(TransactionsListContext.Provider, { value: contextValues, children: jsxRuntime.jsx(QuotesWrapper, {}) }));
@@ -23068,7 +23078,7 @@ function QuotesWrapper() {
23068
23078
  const filter = filterFromContext || (search ? `filter: "quote.id is ${search}"` : '');
23069
23079
  // Queries
23070
23080
  const { data } = reactQuery.useQuery({
23071
- queryKey: ['quotes', token, filter],
23081
+ queryKey: QueryKeyFactory.quotesKey(filter, token),
23072
23082
  queryFn: () => getQuotes({ token, apiHost, filter }),
23073
23083
  placeholderData: reactQuery.keepPreviousData,
23074
23084
  });
@@ -23830,15 +23840,6 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
23830
23840
  setInitialQuote(data === null || data === void 0 ? void 0 : data.quote);
23831
23841
  handleRecalculateTaxes((_b = data === null || data === void 0 ? void 0 : data.quote) === null || _b === void 0 ? void 0 : _b.id);
23832
23842
  },
23833
- onError: (error) => {
23834
- const errorMessage = error.response.errors[0].message;
23835
- if (errorMessage.includes("Address couldn't be validated")) {
23836
- showErrorNotification$2('Please enter a valid billing address');
23837
- }
23838
- else {
23839
- showErrorNotification$2(errorMessage);
23840
- }
23841
- },
23842
23843
  });
23843
23844
  // Queries
23844
23845
  const { data: maskedPriceList, isLoading: isLoadingPriceList } = reactQuery.useQuery({
@@ -5,6 +5,7 @@ export declare const QuoteButtons_FormattedQuoteFragment: import("gql.tada").Tad
5
5
  currency: string | null;
6
6
  amount: number;
7
7
  expiresAt: unknown;
8
+ state: "APPROVED" | "REJECTED" | "DRAFT" | "SHARED" | "VIEWED" | "ACCEPTED" | "IN_APPROVAL" | "UNDONE";
8
9
  }, {}, {
9
10
  fragment: "QuoteButtons_FormattedQuoteFragment";
10
11
  on: "FormattedQuote";
@@ -78,6 +78,7 @@ declare const QueryKeyFactory: {
78
78
  brandingKey: (token?: string) => string[];
79
79
  calculatedPricesKey: ({ priceListId, quantity, token }: CalculatedPricesKeyParams) => (string | number)[];
80
80
  createEventsKey: ({ entityId, pluralType, token }: EventsKeyParams) => string[];
81
+ quotesKey: (filter?: string, token?: string) => string[];
81
82
  createFormattedInvoiceKey: ({ id, token }: FormattedInvoiceKeyParams) => (string | null | undefined)[];
82
83
  createInvoiceKey: ({ id, token }: InvoiceKeyParams) => (string | undefined)[];
83
84
  createObjectKey: ({ id, objectName, token }: ObjectKeyParams) => string[];
package/dist/esm/index.js CHANGED
@@ -1217,6 +1217,11 @@ const QueryKeyFactory = {
1217
1217
  entityId,
1218
1218
  ...(token ? [token] : []),
1219
1219
  ],
1220
+ quotesKey: (filter, token) => [
1221
+ 'quotes',
1222
+ ...(filter ? [filter] : []),
1223
+ ...(token ? [token] : []),
1224
+ ],
1220
1225
  createFormattedInvoiceKey: ({ id, token }) => [
1221
1226
  'formattedInvoice',
1222
1227
  id,
@@ -1281,7 +1286,7 @@ const DEFAULT_CONFIG = {
1281
1286
  };
1282
1287
 
1283
1288
  // This will be replaced at build time by rollup-plugin-replace
1284
- const PACKAGE_VERSION = '1.8.0-beta.12';
1289
+ const PACKAGE_VERSION = '1.8.0-beta.14';
1285
1290
  const createRequestHeaders = (token) => {
1286
1291
  const headers = createClientDevHeaders({ token });
1287
1292
  // Add the components version header
@@ -22163,6 +22168,7 @@ const QuoteButtons_FormattedQuoteFragment = t(`
22163
22168
  currency
22164
22169
  amount
22165
22170
  expiresAt
22171
+ state
22166
22172
  }
22167
22173
  `);
22168
22174
  const PaymentHoldDisplay_QuoteButtonsFragment = t(`
@@ -22179,10 +22185,11 @@ function QuoteButtons({ isAccepted, formattedQuote: maskedFormattedQuote, isMobi
22179
22185
  const { secondaryColor } = useBrand();
22180
22186
  const downloadFile = useDownloadFile(id);
22181
22187
  const isExpired = useIsExpired(formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.expiresAt);
22188
+ const isRejected = (formattedQuote === null || formattedQuote === void 0 ? void 0 : formattedQuote.state) === 'REJECTED';
22182
22189
  const signingPlugins = useSigningPlugins({ apiHost, token });
22183
22190
  return (jsxs("div", { className: "flex flex-row justify-end items-center gap-4", id: "acceptance", style: {
22184
22191
  color: secondaryColor,
22185
- }, children: [isAccepted && formattedQuote.acceptedAt ? (jsx(Text$y, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsx(Button, { icon: jsx(DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsx(Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsx(Fragment, { children: !isAccepted ? (jsx(Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
22192
+ }, children: [isAccepted && formattedQuote.acceptedAt ? (jsx(Text$y, { children: `Quote was accepted by ${formattedQuote.acceptedByName} on ${formatDate(formattedQuote.acceptedAt)}` })) : null, (!isMobile || !isAccepted) && (jsxs("div", { className: isMobile ? 'flex w-full justify-end gap-2' : 'flex items-center justify-end gap-2', children: [paymentHold ? (jsx(PaymentHoldDisplay, { paymentHold: paymentHold, currency: formattedQuote.currency, amount: formattedQuote.amount })) : null, !isMobile && !hideDownloadButton ? (jsx(Button, { icon: jsx(DownloadOutlined, {}), onClick: () => downloadFile(apiHost + '/api/pdf/quote', token), children: "Download" })) : null, shouldDoPaymentHold && !paymentHoldCompleted ? (jsx(Button, { disabled: isExpired, onClick: () => setPaymentHoldModalVisible(true), type: "primary", loading: isSendAcceptPending, children: "Pay and sign" })) : (jsx(Fragment, { children: !isAccepted && !isRejected ? (jsx(Button, { disabled: isExpired || isAccepting, onClick: handleClickAccept, type: "primary", children: isExpired
22186
22193
  ? 'Quote is expired'
22187
22194
  : (signingPlugins === null || signingPlugins === void 0 ? void 0 : signingPlugins.length)
22188
22195
  ? 'Start signing'
@@ -22982,7 +22989,7 @@ function TransactionsDisplay({ transactions, onSearchValueChanged, search, }) {
22982
22989
  onTransactionDisplayClose === null || onTransactionDisplayClose === void 0 ? void 0 : onTransactionDisplayClose(selectedTransaction);
22983
22990
  setDrawerOpen(false);
22984
22991
  }
22985
- return (jsxs("div", { style: style, children: [jsxs("div", { className: `bunny-flex bunny-flex-col bunny-w-full bunny-shadow-padding-xb bunny-gap-2 ${isMobile ? 'bunny-overflow-hidden' : ''} ${className}`, children: [showTitle || showSearchBar ? (jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-col bunny-gap-1' : 'bunny-flex-row bunny-items-center'} bunny-justify-between`, children: [showTitle ? (jsx(Text$s, { className: "bunny-shrink-0 bunny-font-medium", style: { color: darkMode ? undefined : secondaryColor }, children: title })) : (jsx("div", {}) // Empty div so justify-between works
22992
+ return (jsxs("div", { style: style, children: [jsxs("div", { className: `bunny-flex bunny-flex-col bunny-w-full bunny-gap-2 ${isMobile ? 'bunny-overflow-hidden' : ''} ${className}`, children: [showTitle || showSearchBar ? (jsxs("div", { className: `bunny-flex ${isMobile ? 'bunny-flex-col bunny-gap-1' : 'bunny-flex-row bunny-items-center'} bunny-justify-between`, children: [showTitle ? (jsx(Text$s, { className: "bunny-shrink-0 bunny-font-medium", style: { color: darkMode ? undefined : secondaryColor }, children: title })) : (jsx("div", {}) // Empty div so justify-between works
22986
22993
  ), showSearchBar && (jsx("div", { className: `${isMobile ? 'bunny-w-full' : ''}`, children: jsx(Input, { className: searchBarClassName ? searchBarClassName : '', onChange: e => {
22987
22994
  const value = e.target.value;
22988
22995
  // Allow empty string, numbers, and decimal point
@@ -23000,6 +23007,7 @@ function TransactionsDisplay({ transactions, onSearchValueChanged, search, }) {
23000
23007
 
23001
23008
  function Quotes({ className, columns = ['date', 'title', 'amount', 'download', 'state'], filter, filterQuotes, sort = (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(), noQuotesMessage = 'There are no quotes', onQuoteClick, renderQuote, searchBarClassName, shadow = 'shadow-md', showSearchBar = true, showTitle = true, title = 'Past quotes', style, suppressQuoteDisplay = false, useModal = false, }) {
23002
23009
  const { apiHost } = useContext(BunnyContext);
23010
+ const queryClient = useQueryClient();
23003
23011
  const [component, setComponent] = useState(null);
23004
23012
  const contextValues = {
23005
23013
  columns,
@@ -23052,7 +23060,9 @@ function Quotes({ className, columns = ['date', 'title', 'amount', 'download', '
23052
23060
  setComponent(renderQuote(quote));
23053
23061
  }
23054
23062
  else {
23055
- setComponent(jsx(Quote, { id: quote === null || quote === void 0 ? void 0 : quote.transactionableId }));
23063
+ setComponent(jsx(Quote, { id: quote === null || quote === void 0 ? void 0 : quote.transactionableId, onQuoteAccepted: () => {
23064
+ queryClient.invalidateQueries({ queryKey: QueryKeyFactory.quotesKey() });
23065
+ } }));
23056
23066
  }
23057
23067
  }
23058
23068
  return (jsx(TransactionsListContext.Provider, { value: contextValues, children: jsx(QuotesWrapper, {}) }));
@@ -23066,7 +23076,7 @@ function QuotesWrapper() {
23066
23076
  const filter = filterFromContext || (search ? `filter: "quote.id is ${search}"` : '');
23067
23077
  // Queries
23068
23078
  const { data } = useQuery({
23069
- queryKey: ['quotes', token, filter],
23079
+ queryKey: QueryKeyFactory.quotesKey(filter, token),
23070
23080
  queryFn: () => getQuotes({ token, apiHost, filter }),
23071
23081
  placeholderData: keepPreviousData,
23072
23082
  });
@@ -23828,15 +23838,6 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
23828
23838
  setInitialQuote(data === null || data === void 0 ? void 0 : data.quote);
23829
23839
  handleRecalculateTaxes((_b = data === null || data === void 0 ? void 0 : data.quote) === null || _b === void 0 ? void 0 : _b.id);
23830
23840
  },
23831
- onError: (error) => {
23832
- const errorMessage = error.response.errors[0].message;
23833
- if (errorMessage.includes("Address couldn't be validated")) {
23834
- showErrorNotification$2('Please enter a valid billing address');
23835
- }
23836
- else {
23837
- showErrorNotification$2(errorMessage);
23838
- }
23839
- },
23840
23841
  });
23841
23842
  // Queries
23842
23843
  const { data: maskedPriceList, isLoading: isLoadingPriceList } = useQuery({
@@ -5,6 +5,7 @@ export declare const QuoteButtons_FormattedQuoteFragment: import("gql.tada").Tad
5
5
  currency: string | null;
6
6
  amount: number;
7
7
  expiresAt: unknown;
8
+ state: "APPROVED" | "REJECTED" | "DRAFT" | "SHARED" | "VIEWED" | "ACCEPTED" | "IN_APPROVAL" | "UNDONE";
8
9
  }, {}, {
9
10
  fragment: "QuoteButtons_FormattedQuoteFragment";
10
11
  on: "FormattedQuote";
@@ -78,6 +78,7 @@ declare const QueryKeyFactory: {
78
78
  brandingKey: (token?: string) => string[];
79
79
  calculatedPricesKey: ({ priceListId, quantity, token }: CalculatedPricesKeyParams) => (string | number)[];
80
80
  createEventsKey: ({ entityId, pluralType, token }: EventsKeyParams) => string[];
81
+ quotesKey: (filter?: string, token?: string) => string[];
81
82
  createFormattedInvoiceKey: ({ id, token }: FormattedInvoiceKeyParams) => (string | null | undefined)[];
82
83
  createInvoiceKey: ({ id, token }: InvoiceKeyParams) => (string | undefined)[];
83
84
  createObjectKey: ({ id, objectName, token }: ObjectKeyParams) => string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunnyapp/components",
3
- "version": "1.8.0-beta.13",
3
+ "version": "1.8.0-beta.15",
4
4
  "description": "Components from the Bunny portal to embed Bunny UI functionality into your application.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",