Skip to content

Instantly share code, notes, and snippets.

@jay-babu
Created February 13, 2026 16:47
Show Gist options
  • Select an option

  • Save jay-babu/081099159c8a280c7a6b944bd5f4b9a4 to your computer and use it in GitHub Desktop.

Select an option

Save jay-babu/081099159c8a280c7a6b944bd5f4b9a4 to your computer and use it in GitHub Desktop.
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 68b29ba4b..28754bf1a 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -25,7 +25,11 @@
"Bash(npx agent-browser:*)",
"Bash(source .env)",
"Bash(npx stably test:*)",
- "mcp__context7__query-docs"
+ "mcp__context7__query-docs",
+ "Bash(npm view:*)",
+ "Bash(python3:*)",
+ "Bash(npm install:*)",
+ "Bash(npx storybook@9 upgrade:*)"
],
"deny": []
},
diff --git a/.github/workflows/stably-test.yml b/.github/workflows/stably-test.yml
index 825c85de4..3b71f22be 100644
--- a/.github/workflows/stably-test.yml
+++ b/.github/workflows/stably-test.yml
@@ -30,23 +30,23 @@ jobs:
continue-on-error: true
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
- STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
+ STABLY_PROJECT_ID: ${{ vars.STABLY_PROJECT_ID }}
email: ${{ vars.EMAIL }}
password: ${{ secrets.PASSWORD }}
employeePin: ${{ secrets.EMPLOYEE_PIN }}
TEST_BASE_URL: ${{ vars.TEST_BASE_URL }}
- run: npx stably test
+ run: npx stably test --verbose
- name: Fix failing tests (optional)
if: steps.test.outcome == 'failure'
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
- STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
+ STABLY_PROJECT_ID: ${{ vars.STABLY_PROJECT_ID }}
email: ${{ vars.EMAIL }}
password: ${{ secrets.PASSWORD }}
employeePin: ${{ secrets.EMPLOYEE_PIN }}
TEST_BASE_URL: ${{ vars.TEST_BASE_URL }}
- run: npx stably fix
+ run: npx stably fix --verbose
- name: Fail if tests failed
if: steps.test.outcome == 'failure'
diff --git a/.storybook/main.ts b/.storybook/main.ts
index 1f618666a..c754b5e40 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -1,4 +1,3 @@
-import { withoutVitePlugins } from "@storybook/builder-vite";
import type { StorybookConfig } from "@storybook/react-vite";
import path from "node:path";
import tsconfigPaths from "vite-tsconfig-paths";
@@ -8,9 +7,8 @@ const config: StorybookConfig = {
addons: [
"@storybook/addon-onboarding",
"@storybook/addon-links",
- "@storybook/addon-essentials",
"@chromatic-com/storybook",
- "@storybook/addon-interactions",
+ "@storybook/addon-docs"
],
framework: {
name: "@storybook/react-vite",
@@ -18,17 +16,6 @@ const config: StorybookConfig = {
},
staticDirs: ["../public"],
viteFinal: async (config) => {
- const plugins = await withoutVitePlugins(config.plugins, [
- "vite-plugin-pwa",
- "vite-plugin-pwa:info",
- "vite-plugin-pwa:build",
- "vite-plugin-pwa:dev-sw",
- "vite-plugin-pwa:pwa-assets",
- "vite-plugin-pwa:register",
- "vite-plugin-eslint",
- "@mdx-js/rollup",
- ]);
- console.log(plugins);
return {
...config,
resolve: {
@@ -47,7 +34,7 @@ const config: StorybookConfig = {
optimizeDeps: {
...config.optimizeDeps,
entries: [
- `${path.relative(config.root, path.resolve(__dirname, "../src"))}/**/*.stories.tsx`,
+ `${path.relative(config.root!, path.resolve(__dirname, "../src"))}/**/*.stories.tsx`,
],
include: [...(config.optimizeDeps?.include ?? [])],
exclude: ["node_modules/.cache/storybook"],
@@ -58,7 +45,7 @@ const config: StorybookConfig = {
...config.build?.rollupOptions,
},
},
- plugins: [...plugins, tsconfigPaths()],
+ plugins: [...(config.plugins ?? []), tsconfigPaths()],
};
},
};
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index 66dfe5ad2..788b3631b 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -1,4 +1,4 @@
-import type { Preview } from "@storybook/react";
+import type { Preview } from "@storybook/react-vite";
import { initialize, mswLoader } from "msw-storybook-addon";
import { handlers as generatedHandlers } from "../src/generated/msw/handlers";
import "../src/index.css"; // replace with the name of your tailwind css file
diff --git a/package.json b/package.json
index 2222f8489..98d01aa7b 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"@intercom/messenger-js-sdk": "^0.0.18",
"@mdx-js/react": "^3.1.0",
"@mdx-js/rollup": "^3.1.0",
+ "@point-of-sale/receipt-printer-encoder": "^3.0.3",
"@point-of-sale/webhid-barcode-scanner": "^1.2.1",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
@@ -111,6 +112,7 @@
"re-resizable": "^6.9.11",
"react": "^18.2.0",
"react-apexcharts": "1.4.1",
+ "react-confetti": "^6.4.0",
"react-credit-cards-2": "^1.0.2",
"react-day-picker": "^9.11.0",
"react-dom": "^18.2.0",
@@ -139,7 +141,6 @@
"swagger-typescript-api": "^13.0.3",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
- "@point-of-sale/receipt-printer-encoder": "^3.0.3",
"typeid-js": "^1.2.0",
"typescript": "^5.3.3",
"use-debounce": "^10.0.0",
@@ -147,8 +148,8 @@
"usehooks-ts": "^2.16.0",
"uuid": "^9.0.1",
"vaul": "^0.9.2",
- "vite": "^5.4.19",
- "vite-tsconfig-paths": "^4.3.1",
+ "vite": "^7.3.1",
+ "vite-tsconfig-paths": "^6.1.0",
"web-vitals": "^2.1.4",
"yup": "^1.2.0",
"zod": "^3.23.8"
@@ -156,6 +157,7 @@
"scripts": {
"start": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite",
"build": "tsc && vite build",
+ "preview": "vite preview --port 3000",
"build:prod": "tsc && vite build --mode production",
"build:gamma": "tsc && vite build --mode staging",
"test": "npx vitest",
@@ -183,8 +185,7 @@
]
},
"devDependencies": {
- "@chakra-ui/storybook-addon": "^5.1.0",
- "@chromatic-com/storybook": "^1.5.0",
+ "@chromatic-com/storybook": "^4.1.3",
"@emotion/styled": "^11.14.0",
"@eslint/compat": "^1.2.9",
"@eslint/eslintrc": "^3.3.1",
@@ -207,17 +208,12 @@
"@pulumi/pulumi": "^3.113.0",
"@sentry/vite-plugin": "^2.16.1",
"@stablyai/playwright-test": "^2.0.13",
- "@storybook/addon-essentials": "^8.1.0",
- "@storybook/addon-interactions": "^8.1.0",
- "@storybook/addon-links": "^8.1.0",
- "@storybook/addon-onboarding": "^1.0.10",
- "@storybook/blocks": "^8.1.0",
- "@storybook/react": "^8.1.0",
- "@storybook/react-vite": "^8.1.0",
- "@storybook/react-webpack5": "^8.1.0",
- "@storybook/test": "^8.1.0",
- "@storybook/test-runner": "^0.16.0",
- "@storybook/testing-library": "^0.2.2",
+ "@storybook/addon-docs": "9.1.17",
+ "@storybook/addon-links": "9.1.17",
+ "@storybook/addon-onboarding": "9.1.17",
+ "@storybook/react-vite": "9.1.17",
+ "@storybook/react-webpack5": "9.1.17",
+ "@storybook/test-runner": "^0.23.0",
"@tailwindcss/forms": "^0.5.7",
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -229,8 +225,10 @@
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.0.0",
"@types/papaparse": "^5.3.16",
+ "@types/qs": "^6.14.0",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
+ "@types/uuid": "^10.0.0",
"@types/w3c-web-usb": "^1.0.10",
"@typescript-eslint/eslint-plugin": "^8.32.1",
"@vitest/coverage-v8": "^3.1.4",
@@ -240,7 +238,7 @@
"eslint": "^9.26.0",
"eslint-config-prettier": "^8.9.0",
"eslint-plugin-react-hooks": "5.2.0",
- "eslint-plugin-storybook": "^0.6.15",
+ "eslint-plugin-storybook": "9.1.17",
"fake-indexeddb": "^6.2.4",
"http-server": "^14.1.1",
"husky": "^8.0.3",
@@ -252,13 +250,13 @@
"prettier": "^3.8.1",
"prettier-plugin-organize-imports": "^4.3.0",
"prop-types": "^15.8.1",
- "storybook": "^8.6.15",
+ "storybook": "9.1.17",
"tailwindcss": "^3.4.1",
"ts-jest": "^29.1.4",
"tsx": "^4.20.5",
- "vite-plugin-checker": "^0.6.4",
+ "vite-plugin-checker": "^0.12.0",
"vite-plugin-eslint": "^1.8.1",
- "vite-plugin-pwa": "^1.0.3",
+ "vite-plugin-pwa": "^1.2.0",
"vite-plugin-wasm": "^3.5.0",
"vitest": "^3.1.4",
"wait-on": "^7.2.0",
diff --git a/playwright.config.ts b/playwright.config.ts
index 026c59ada..985b32978 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -25,14 +25,16 @@ const isLocalhost = baseURL === "http://localhost:3000";
*/
export default defineConfig({
testDir: "./e2e",
+ /* Ignore seed files - they are used for test generation setup, not actual tests */
+ testIgnore: ["**/*seed*.spec.ts"],
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
- /* Opt out of parallel tests on CI. */
- workers: process.env.CI ? 1 : undefined,
+ /* Run tests in parallel with 2 workers on CI. */
+ workers: process.env.CI ? 2 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [
["html"],
@@ -63,9 +65,12 @@ export default defineConfig({
/* Run your local dev server before starting the tests - skip if using external URL */
webServer: isLocalhost
? {
+ // Use production build + preview server instead of dev server
+ // This avoids service worker flakiness that only occurs with the Vite dev server
command: "npm run start",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
+ timeout: 120000,
}
: undefined,
});
diff --git a/src/components/Auth/AuthorizationFlowForms/EnterEmployeePinForm.stories.tsx b/src/components/Auth/AuthorizationFlowForms/EnterEmployeePinForm.stories.tsx
index 45680df20..d6ff8e98b 100644
--- a/src/components/Auth/AuthorizationFlowForms/EnterEmployeePinForm.stories.tsx
+++ b/src/components/Auth/AuthorizationFlowForms/EnterEmployeePinForm.stories.tsx
@@ -1,5 +1,5 @@
-import { action } from "@storybook/addon-actions";
-import { Meta, StoryObj } from "@storybook/react";
+import { action } from "storybook/actions";
+import { Meta, StoryObj } from "@storybook/react-vite";
import { UserDTO } from "model/data-contracts";
import { useState } from "react";
import { EnterEmployeePinForm } from "./EnterEmployeePinForm";
diff --git a/src/components/SalesScreenComponents/Modals/DriversLicenseScannerModal/DriversLicenseScannerModal.stories.tsx b/src/components/SalesScreenComponents/Modals/DriversLicenseScannerModal/DriversLicenseScannerModal.stories.tsx
index 16e8faed3..1a99f6365 100644
--- a/src/components/SalesScreenComponents/Modals/DriversLicenseScannerModal/DriversLicenseScannerModal.stories.tsx
+++ b/src/components/SalesScreenComponents/Modals/DriversLicenseScannerModal/DriversLicenseScannerModal.stories.tsx
@@ -1,6 +1,6 @@
import { ChakraProvider } from "@chakra-ui/react";
-import type { Meta, StoryObj } from "@storybook/react";
-import { fn } from "@storybook/test";
+import type { Meta, StoryObj } from "@storybook/react-vite";
+import { fn } from "storybook/test";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MockEntityProvider } from "src/test/mocks/entityProvider";
import { DriversLicenseScannerModal } from "./DriversLicenseScannerModal";
diff --git a/src/components/SalesScreenComponents/Modals/payments/PayWithHouseAccount.stories.tsx b/src/components/SalesScreenComponents/Modals/payments/PayWithHouseAccount.stories.tsx
index de8545586..9be658046 100644
--- a/src/components/SalesScreenComponents/Modals/payments/PayWithHouseAccount.stories.tsx
+++ b/src/components/SalesScreenComponents/Modals/payments/PayWithHouseAccount.stories.tsx
@@ -1,6 +1,6 @@
-import { action } from "@storybook/addon-actions";
-import { Meta, StoryObj } from "@storybook/react";
-import { expect, within } from "@storybook/test";
+import { action } from "storybook/actions";
+import { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, within } from "storybook/test";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { http, HttpResponse } from "msw";
import { useState } from "react";
diff --git a/src/components/common/BulkActionProgress/BulkActionProgress.stories.tsx b/src/components/common/BulkActionProgress/BulkActionProgress.stories.tsx
index 58338a6fa..3d01baaeb 100644
--- a/src/components/common/BulkActionProgress/BulkActionProgress.stories.tsx
+++ b/src/components/common/BulkActionProgress/BulkActionProgress.stories.tsx
@@ -1,5 +1,5 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { expect, userEvent, waitFor, within } from "@storybook/test";
+import type { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, userEvent, waitFor, within } from "storybook/test";
import { useEffect, useState } from "react";
import { BulkActionProgress } from "./BulkActionProgress";
import { BulkActionFeedback } from "./types";
diff --git a/src/components/common/EmployeePinInput/EmployeePinInput.stories.tsx b/src/components/common/EmployeePinInput/EmployeePinInput.stories.tsx
index 63cb4fc9f..5889a7156 100644
--- a/src/components/common/EmployeePinInput/EmployeePinInput.stories.tsx
+++ b/src/components/common/EmployeePinInput/EmployeePinInput.stories.tsx
@@ -1,5 +1,5 @@
-import { Meta, StoryObj } from "@storybook/react";
-import { expect, userEvent, waitFor, within } from "@storybook/test";
+import { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, fn, userEvent, waitFor, within } from "storybook/test";
import { useState } from "react";
import { EmployeePinInput } from "./EmployeePinInput";
@@ -9,6 +9,12 @@ const meta = {
parameters: {
layout: "centered",
},
+ args: {
+ onChange: fn(),
+ onComplete: fn(),
+ onFocus: fn(),
+ onBlur: fn(),
+ },
argTypes: {
value: {
control: { type: "text" },
@@ -27,11 +33,9 @@ const meta = {
description: "Additional CSS classes to apply",
},
onChange: {
- action: "changed",
description: "Callback fired when the value changes",
},
onComplete: {
- action: "completed",
description: "Callback fired when all 4 digits are entered",
},
},
diff --git a/src/components/common/LearnMoreAccordion/LearnMoreAccordion.stories.tsx b/src/components/common/LearnMoreAccordion/LearnMoreAccordion.stories.tsx
index 3f997f11d..acafadf54 100644
--- a/src/components/common/LearnMoreAccordion/LearnMoreAccordion.stories.tsx
+++ b/src/components/common/LearnMoreAccordion/LearnMoreAccordion.stories.tsx
@@ -1,5 +1,5 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { expect, userEvent, waitFor, within } from "@storybook/test";
+import type { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, userEvent, waitFor, within } from "storybook/test";
import { useState } from "react";
import { LearnMoreAccordion } from "./LearnMoreAccordion";
diff --git a/src/components/common/SavingIndicator/SavingIndicator.stories.tsx b/src/components/common/SavingIndicator/SavingIndicator.stories.tsx
index ee6d48c82..8fae2e50f 100644
--- a/src/components/common/SavingIndicator/SavingIndicator.stories.tsx
+++ b/src/components/common/SavingIndicator/SavingIndicator.stories.tsx
@@ -1,4 +1,4 @@
-import { Meta, StoryObj } from "@storybook/react";
+import { Meta, StoryObj } from "@storybook/react-vite";
import { SavingIndicator } from "./SavingIndicator";
const meta = {
diff --git a/src/components/common/StyledPaginationControls/StyledPaginationControls.stories.tsx b/src/components/common/StyledPaginationControls/StyledPaginationControls.stories.tsx
index 2c5c185d0..94f7ae28d 100644
--- a/src/components/common/StyledPaginationControls/StyledPaginationControls.stories.tsx
+++ b/src/components/common/StyledPaginationControls/StyledPaginationControls.stories.tsx
@@ -1,4 +1,4 @@
-import { Meta, StoryObj } from "@storybook/react";
+import { Meta, StoryObj } from "@storybook/react-vite";
import { MemoryRouter } from "react-router-dom";
import { StyledPaginationControls } from "./StyledPaginationControls";
diff --git a/src/components/invoices/__tests__/InvoiceStatusTag.stories.tsx b/src/components/invoices/__tests__/InvoiceStatusTag.stories.tsx
index 3e7623d33..ae7df2264 100644
--- a/src/components/invoices/__tests__/InvoiceStatusTag.stories.tsx
+++ b/src/components/invoices/__tests__/InvoiceStatusTag.stories.tsx
@@ -1,5 +1,5 @@
-import { Meta, StoryObj } from "@storybook/react";
-import { expect, within } from "@storybook/test";
+import { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, within } from "storybook/test";
import { InvoiceStatus } from "model/data-contracts";
import { InvoiceStatusTag } from "../InvoiceStatusTag";
diff --git a/src/components/loyalty/CustomerProfile/HouseAccount/HouseAccountCurrentBalance.stories.tsx b/src/components/loyalty/CustomerProfile/HouseAccount/HouseAccountCurrentBalance.stories.tsx
index b30cfa8f5..68dd3d2d4 100644
--- a/src/components/loyalty/CustomerProfile/HouseAccount/HouseAccountCurrentBalance.stories.tsx
+++ b/src/components/loyalty/CustomerProfile/HouseAccount/HouseAccountCurrentBalance.stories.tsx
@@ -1,4 +1,4 @@
-import { Meta, StoryObj } from "@storybook/react";
+import { Meta, StoryObj } from "@storybook/react-vite";
import { HouseAccountCurrentBalance } from "./HouseAccountCurrentBalance";
const meta = {
diff --git a/src/components/loyalty/CustomerProfile/NewCustomerForm.stories.tsx b/src/components/loyalty/CustomerProfile/NewCustomerForm.stories.tsx
index 0d6d2afd9..390c25c62 100644
--- a/src/components/loyalty/CustomerProfile/NewCustomerForm.stories.tsx
+++ b/src/components/loyalty/CustomerProfile/NewCustomerForm.stories.tsx
@@ -1,6 +1,6 @@
import { ChakraProvider } from "@chakra-ui/react";
-import type { Meta, StoryObj } from "@storybook/react";
-import { expect, fn, userEvent, within } from "@storybook/test";
+import type { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, fn, userEvent, within } from "storybook/test";
import { MockEntityProvider } from "src/test/mocks/entityProvider";
import { NewCustomerForm } from "./NewCustomerForm";
diff --git a/src/components/po/PurchaseOrderCandidateItems.stories.tsx b/src/components/po/PurchaseOrderCandidateItems.stories.tsx
index ba4c19ff6..4506c12e8 100644
--- a/src/components/po/PurchaseOrderCandidateItems.stories.tsx
+++ b/src/components/po/PurchaseOrderCandidateItems.stories.tsx
@@ -1,7 +1,7 @@
import { defaultHandlers } from ".storybook/preview";
import { ChakraProvider } from "@chakra-ui/react";
-import { Meta, StoryObj } from "@storybook/react";
-import { expect, userEvent, waitFor, within } from "@storybook/test";
+import { Meta, StoryObj } from "@storybook/react-vite";
+import { expect, userEvent, waitFor, within } from "storybook/test";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { http, HttpResponse } from "msw";
import { MemoryRouter } from "react-router-dom";
diff --git a/src/config/statsigBootstrap.ts b/src/config/statsigBootstrap.ts
index 8f555c945..dd28dad8f 100644
--- a/src/config/statsigBootstrap.ts
+++ b/src/config/statsigBootstrap.ts
@@ -13,7 +13,10 @@ export type AuditLogPreset = {
};
// Shared default values for audit log config - used in both Statsig bootstrap and AuditLogsPanelV2.tsx
-export const DEFAULT_AUDIT_LOG_CHANGED_FIELDS: Record<string, { value: string; label: string }[]> = {
+export const DEFAULT_AUDIT_LOG_CHANGED_FIELDS: Record<
+ string,
+ { value: string; label: string }[]
+> = {
ITEM: [
{ value: "price", label: "Price" },
{ value: "quantity", label: "Quantity" },
@@ -154,7 +157,9 @@ export const STATSIG_BOOTSTRAP_VALUES = {
},
},
},
- feature_gates: {},
+ feature_gates: {
+ department_entity_tax: true,
+ },
layer_configs: {},
has_updates: true,
time: Date.now(),
diff --git a/src/context/DepartmentContext.tsx b/src/context/DepartmentContext.tsx
index 074166bb6..6c6fc675c 100644
--- a/src/context/DepartmentContext.tsx
+++ b/src/context/DepartmentContext.tsx
@@ -19,10 +19,12 @@ import {
DepartmentGroup,
listDepartmentGroupsQueryOptions,
listDepartmentsQueryOptions,
+ ListDepartmentsQueryParams,
} from "src/spring-generated";
import { mapPgLiteQueryFn, useAutoOfflineQuery } from "utils/offlineUtils";
import { useCohortIdProvider } from "./CohortProvider";
import { useEntity } from "./EntityProvider";
+import { useFeatureFlagCallback } from "hooks/usePostHogFeatureFlag";
/**
* Maps PGLite department data to API format
@@ -61,9 +63,23 @@ const useGetAllDepartmentsForEntityInternal = () => {
const queryClient = useQueryClient();
const pgLiteDb = usePGliteOptional();
+ const { checkGate } = useFeatureFlagCallback({
+ flag: "department_entity_tax",
+ defaultValue: false,
+ });
+
+ const listDepartmentsQueryParams: ListDepartmentsQueryParams = useMemo(() => {
+ return {
+ entityId: entity?.id ?? 0,
+ featureFlags: [checkGate() ? "department_entity_tax" : undefined].filter(
+ (f) => f !== undefined,
+ ),
+ };
+ }, [entity?.id, checkGate]);
+
const { data, isFetching, queryKey } = useAutoOfflineQuery(
{
- ...listDepartmentsQueryOptions(),
+ ...listDepartmentsQueryOptions(listDepartmentsQueryParams),
enabled: !!entity?.cohortId,
refetchOnWindowFocus: false,
refetchOnMount: false,
diff --git a/src/pages/NotFoundPage.stories.tsx b/src/pages/NotFoundPage.stories.tsx
index c0922567c..93705d848 100644
--- a/src/pages/NotFoundPage.stories.tsx
+++ b/src/pages/NotFoundPage.stories.tsx
@@ -1,4 +1,4 @@
-import { Meta, StoryObj } from "@storybook/react";
+import { Meta, StoryObj } from "@storybook/react-vite";
import { MemoryRouter } from "react-router-dom";
import { QueryParamProvider } from "use-query-params";
import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6";
diff --git a/src/pages/TransactionPage.tsx b/src/pages/TransactionPage.tsx
index e144d58ce..f3a1ee62a 100644
--- a/src/pages/TransactionPage.tsx
+++ b/src/pages/TransactionPage.tsx
@@ -76,6 +76,7 @@ import {
} from "src/spring-generated";
import { FinishTransacationPaymentModal } from "../components/TransactionsComponents/FinishTransactionPaymentModal";
import { useTransactionReceipt } from "../components/TransactionsComponents/useTransactionReceipt";
+import { extractAxios400ErrorMessage } from "utils/errors";
const CANCELABLE_TRANSACTION_STATUS = new Set([
TransactionStatus.CREATED,
@@ -233,7 +234,7 @@ const TransactionPage = () => {
onError: (err: any) => {
toast({
title: "Error",
- description: err.response?.data?.message,
+ description: extractAxios400ErrorMessage(err),
variant: "destructive",
});
captureException(err);
@@ -610,7 +611,11 @@ const TransactionPage = () => {
variant="destructive"
onClick={async () => {
if (!txId) return;
- await deleteTransaction({} as never);
+ try {
+ await deleteTransaction({} as never);
+ } catch {
+ // Error handled in onError callback
+ }
}}
>
<Button
diff --git a/src/pages/inventory/InventoryCountInputPage.tsx b/src/pages/inventory/InventoryCountInputPage.tsx
index 4f3e970f4..07c86b746 100644
--- a/src/pages/inventory/InventoryCountInputPage.tsx
+++ b/src/pages/inventory/InventoryCountInputPage.tsx
@@ -50,7 +50,13 @@ export type AddForm = {
const columnHelper = createColumnHelper<InventoryCountItemOutput>();
-export const DeleteInventoryCountItemButton = ({ id }: { id: number }) => {
+export const DeleteInventoryCountItemButton = ({
+ id,
+ disabled,
+}: {
+ id: number;
+ disabled?: boolean;
+}) => {
const queryClient = useQueryClient();
const { mutateAsync: deleteItem, isPending } =
@@ -70,6 +76,7 @@ export const DeleteInventoryCountItemButton = ({ id }: { id: number }) => {
colorScheme="red"
icon={<DeleteIcon />}
isLoading={isPending}
+ isDisabled={disabled}
onClick={() => deleteItem({} as never)}
></IconButton>
);
@@ -111,6 +118,12 @@ export const InventoryCountInputPage: React.FC<
const countInputRef = useRef<HTMLInputElement>(null);
const toast = useToast();
+ const inventoryCount = useGetInventoryCountById(id, {
+ zoneId: Intl.DateTimeFormat().resolvedOptions().timeZone,
+ });
+
+ const isCompleted = inventoryCount.data?.result.status === "COMPLETE";
+
const { data, isLoading, queryKey } = useGetInventoryCountItemsById(
id,
{
@@ -240,18 +253,19 @@ export const InventoryCountInputPage: React.FC<
columnHelper.display({
header: " ",
cell: ({ row }) => (
- <DeleteInventoryCountItemButton id={row.original.id} />
+ <DeleteInventoryCountItemButton
+ id={row.original.id}
+ disabled={isCompleted}
+ />
),
}),
];
- }, []);
-
- const d = useGetInventoryCountById(id, {
- zoneId: "",
- });
+ }, [isCompleted]);
useDocumentTitle(
- d.data ? `Inventory Count: ${d.data.result.name}` : undefined,
+ inventoryCount.data
+ ? `Inventory Count: ${inventoryCount.data.result.name}`
+ : undefined,
);
return (
@@ -259,8 +273,8 @@ export const InventoryCountInputPage: React.FC<
<CardHeader>
<HStack w="100%" justifyContent="space-between">
<HStack>
- <Heading size="md">{d.data?.result.name}</Heading>
- <Spinner hidden={!isLoading || !d.isLoading} />
+ <Heading size="md">{inventoryCount.data?.result.name}</Heading>
+ <Spinner hidden={!isLoading || !inventoryCount.isLoading} />
</HStack>
</HStack>
</CardHeader>
@@ -290,6 +304,7 @@ export const InventoryCountInputPage: React.FC<
countInputRef.current?.focus();
countInputRef.current?.select();
}}
+ isDisabled={isCompleted}
/>
)}
/>
@@ -309,6 +324,7 @@ export const InventoryCountInputPage: React.FC<
onValueChange={(value) => {
field.onChange(value);
}}
+ disabled={isCompleted}
/>
)}
/>
@@ -317,7 +333,7 @@ export const InventoryCountInputPage: React.FC<
requires="inventory_count/*:count"
type="submit"
isLoading={isPending}
- disabled={isPending}
+ disabled={isPending || isCompleted}
leftIcon={<AddIcon />}
>
Add
@@ -337,6 +353,7 @@ export const InventoryCountInputPage: React.FC<
}
setSearchState(val);
}}
+ disabled={isCompleted}
/>
<TransformityDataTable
variant="pretty"
diff --git a/src/test/mocks/MockPointerEvent.ts b/src/test/mocks/MockPointerEvent.ts
index 2972bf335..7498c294d 100644
--- a/src/test/mocks/MockPointerEvent.ts
+++ b/src/test/mocks/MockPointerEvent.ts
@@ -1,4 +1,4 @@
-import { fn } from "@storybook/test";
+import { fn } from "storybook/test";
export class MockPointerEvent extends Event {
button: number;
diff --git a/stably.yaml b/stably.yaml
new file mode 100644
index 000000000..2824af685
--- /dev/null
+++ b/stably.yaml
@@ -0,0 +1,27 @@
+# Stably Configuration
+# Scheduled test runs for production, beta, and gamma environments
+
+schedules:
+ production-every-30min:
+ cron: "*/30 * * * *"
+ stablyTestArgs: "--project chromium"
+ env:
+ TEST_BASE_URL: "https://pos.transformity.tech"
+
+ beta-every-30min:
+ cron: "*/30 * * * *"
+ stablyTestArgs: "--project chromium"
+ env:
+ TEST_BASE_URL: "https://pos.beta.transformity.tech"
+
+ gamma-every-30min:
+ cron: "*/30 * * * *"
+ stablyTestArgs: "--project chromium"
+ env:
+ TEST_BASE_URL: "https://dev.pos.transformity.tech"
+
+notifications:
+ email:
+ onFailure: true
+ recipients:
+ - issue@transformity.pagerduty.com
diff --git a/vite.config.ts b/vite.config.ts
index bfb58f36f..d4a480962 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -120,4 +120,8 @@ export default defineConfig({
ignored: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
},
},
+ preview: {
+ host: "localhost",
+ port: 3000,
+ },
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment