feature/feature/IO-3554-Form-Row-Layout - Responsive overhaul

This commit is contained in:
Dave
2026-02-26 15:56:57 -05:00
parent 226cc801ae
commit fd6f46e39d
99 changed files with 807 additions and 443 deletions

View File

@@ -18,3 +18,4 @@ VITE_PUBLIC_POSTHOG_KEY=phc_xtLmBIu0rjWwExY73Oj5DTH1bGbwq1G1Y8jnlTceien
VITE_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
VITE_APP_AMP_URL=https://vp8k908qy2.execute-api.ca-central-1.amazonaws.com
VITE_APP_AMP_KEY=6228a598e57cd66875cfd41604f1f891
VITE_APP_ENABLE_RESPONSIVE_TABLE_FILTERING=false

View File

@@ -20,3 +20,4 @@ VITE_PUBLIC_POSTHOG_KEY=phc_xtLmBIu0rjWwExY73Oj5DTH1bGbwq1G1Y8jnlTceien
VITE_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
VITE_APP_AMP_URL=https://vp8k908qy2.execute-api.ca-central-1.amazonaws.com
VITE_APP_AMP_KEY=46b1193a867d4e3131ae4c3a64a3fc78
VITE_APP_ENABLE_RESPONSIVE_TABLE_FILTERING=false

View File

@@ -47,7 +47,7 @@
"i18next": "^25.8.13",
"i18next-browser-languagedetector": "^8.2.1",
"immutability-helper": "^3.1.1",
"libphonenumber-js": "^1.12.37",
"libphonenumber-js": "^1.12.38",
"lightningcss": "^1.31.1",
"logrocket": "^12.0.0",
"markerjs2": "^2.32.7",
@@ -55,7 +55,7 @@
"normalize-url": "^8.1.1",
"object-hash": "^3.0.0",
"phone": "^3.1.71",
"posthog-js": "^1.354.1",
"posthog-js": "^1.355.0",
"prop-types": "^15.8.1",
"query-string": "^9.3.1",
"raf-schd": "^4.0.3",
@@ -4861,9 +4861,9 @@
}
},
"node_modules/@posthog/types": {
"version": "1.354.1",
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.354.1.tgz",
"integrity": "sha512-/d2ubZOcRbKJU5PWSkt8AwR3l/CCv5vPf4RDHIpGptI6ezDf5sTFWdqF088ziS7J3CB03Pax/ubAqsgJUfIy9A==",
"version": "1.355.0",
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.355.0.tgz",
"integrity": "sha512-g9YNcIzSe+BJFKjuea7Hr0DiN83XlmqBXRpIyEJ7t9jVAK2Srf67Y2rI0ZjeNXe2LasOyOvoy7RgnSPBXbNZGw==",
"license": "MIT"
},
"node_modules/@protobufjs/aspromise": {
@@ -12906,9 +12906,9 @@
}
},
"node_modules/libphonenumber-js": {
"version": "1.12.37",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.37.tgz",
"integrity": "sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw==",
"version": "1.12.38",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.38.tgz",
"integrity": "sha512-vwzxmasAy9hZigxtqTbFEwp8ZdZ975TiqVDwj5bKx5sR+zi5ucUQy9mbVTkKM9GzqdLdxux/hTw2nmN5J7POMA==",
"license": "MIT"
},
"node_modules/lightningcss": {
@@ -15049,9 +15049,9 @@
"license": "MIT"
},
"node_modules/posthog-js": {
"version": "1.354.1",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.354.1.tgz",
"integrity": "sha512-ncHYOOglHAsy5H9xogwmfBeqOF8bK58+b2VRv5SdnqiCfUBndo5pgAU9z2zS5MJuXuYbbpbBN0fGafHwmdr+5Q==",
"version": "1.355.0",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.355.0.tgz",
"integrity": "sha512-RpxHyodlr9wuqoZOct8DDg50SGq3SQmUWxYu+G1eOO+PvWsr5N2ZZdhE/rpv2zZccPdbXdgIy3M1pa574Nps7w==",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
"@opentelemetry/api": "^1.9.0",
@@ -15060,7 +15060,7 @@
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-logs": "^0.208.0",
"@posthog/core": "1.23.1",
"@posthog/types": "1.354.1",
"@posthog/types": "1.355.0",
"core-js": "^3.38.1",
"dompurify": "^3.3.1",
"fflate": "^0.4.8",

View File

@@ -46,7 +46,7 @@
"i18next": "^25.8.13",
"i18next-browser-languagedetector": "^8.2.1",
"immutability-helper": "^3.1.1",
"libphonenumber-js": "^1.12.37",
"libphonenumber-js": "^1.12.38",
"lightningcss": "^1.31.1",
"logrocket": "^12.0.0",
"markerjs2": "^2.32.7",
@@ -54,7 +54,7 @@
"normalize-url": "^8.1.1",
"object-hash": "^3.0.0",
"phone": "^3.1.71",
"posthog-js": "^1.354.1",
"posthog-js": "^1.355.0",
"prop-types": "^15.8.1",
"query-string": "^9.3.1",
"raf-schd": "^4.0.3",

View File

@@ -1,7 +1,7 @@
import { ApolloProvider } from "@apollo/client/react";
import * as Sentry from "@sentry/react";
import { SplitFactoryProvider, useSplitClient } from "@splitsoftware/splitio-react";
import { ConfigProvider } from "antd";
import { ConfigProvider, Grid } from "antd";
import enLocale from "antd/es/locale/en_US";
import { useEffect, useMemo } from "react";
import { CookiesProvider } from "react-cookie";
@@ -43,10 +43,47 @@ function AppContainer() {
const currentUser = useSelector(selectCurrentUser);
const isDarkMode = useSelector(selectDarkMode);
const screens = Grid.useBreakpoint();
const isPhone = !screens.md;
const isUltraWide = Boolean(screens.xxxl);
const theme = useMemo(() => getTheme(isDarkMode), [isDarkMode]);
const theme = useMemo(() => {
const baseTheme = getTheme(isDarkMode);
return {
...baseTheme,
token: {
...(baseTheme.token || {}),
screenXXXL: 2160
},
components: {
...(baseTheme.components || {}),
Table: {
...(baseTheme.components?.Table || {}),
cellFontSizeSM: isPhone ? 12 : 13,
cellFontSizeMD: isPhone ? 13 : isUltraWide ? 15 : 14,
cellFontSize: isUltraWide ? 15 : 14,
cellPaddingInlineSM: isPhone ? 8 : 10,
cellPaddingInlineMD: isPhone ? 10 : 14,
cellPaddingInline: isUltraWide ? 20 : 16,
cellPaddingBlockSM: isPhone ? 8 : 10,
cellPaddingBlockMD: isPhone ? 10 : 12,
cellPaddingBlock: isUltraWide ? 14 : 12,
selectionColumnWidth: isPhone ? 44 : 52
}
}
};
}, [isDarkMode, isPhone, isUltraWide]);
const antdInput = useMemo(() => ({ autoComplete: "new-password" }), []);
const antdTable = useMemo(() => ({ scroll: { x: "max-content" } }), []);
const antdPagination = useMemo(
() => ({
showSizeChanger: !isPhone,
totalBoundaryShowSizeChanger: 100
}),
[isPhone]
);
const antdForm = useMemo(
() => ({
@@ -122,7 +159,16 @@ function AppContainer() {
return (
<CookiesProvider>
<ApolloProvider client={client}>
<ConfigProvider input={antdInput} locale={enLocale} theme={theme} form={antdForm}>
<ConfigProvider
input={antdInput}
locale={enLocale}
theme={theme}
form={antdForm}
table={antdTable}
pagination={antdPagination}
componentSize={isPhone ? "small" : isUltraWide ? "large" : "middle"}
popupOverflow="viewport"
>
<GlobalLoadingBar />
<SplitFactoryProvider config={config}>
<SplitClientProvider>

View File

@@ -68,7 +68,7 @@ const currentTheme = import.meta.env.DEV ? devTheme : prodTheme;
const getTheme = (isDarkMode) => ({
algorithm: isDarkMode ? darkAlgorithm : defaultAlgorithm,
...defaultsDeep(currentTheme, defaultTheme)
...defaultsDeep({}, currentTheme, defaultTheme(isDarkMode))
});
export default getTheme;

View File

@@ -1,4 +1,4 @@
import { Card, Checkbox, Input, Space, Table } from "antd";
import { Card, Checkbox, Input, Space } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -16,6 +16,7 @@ import PayableExportAll from "../payable-export-all-button/payable-export-all-bu
import PayableExportButton from "../payable-export-button/payable-export-button.component";
import BillMarkSelectedExported from "../payable-mark-selected-exported/payable-mark-selected-exported.component";
import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import useLocalStorage from "./../../utils/useLocalStorage";
const mapStateToProps = createStructuredSelector({
@@ -179,11 +180,12 @@ export function AccountingPayablesTableComponent({ bodyshop, loading, bills, ref
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
dataSource={dataSource}
pagination={{ placement: "top", pageSize: exportPageLimit, showSizeChanger: false }}
columns={columns}
mobileColumnKeys={["vendorname", "invoice_number", "ro_number", "total", "actions"]}
rowKey="id"
onChange={handleTableChange}
rowSelection={{

View File

@@ -1,4 +1,4 @@
import { Card, Input, Space, Table } from "antd";
import { Card, Input, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -17,6 +17,7 @@ import PaymentExportButton from "../payment-export-button/payment-export-button.
import PaymentMarkSelectedExported from "../payment-mark-selected-exported/payment-mark-selected-exported.component";
import PaymentsExportAllButton from "../payments-export-all-button/payments-export-all-button.component";
import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -192,11 +193,12 @@ export function AccountingPayablesTableComponent({ bodyshop, loading, payments,
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
dataSource={dataSource}
pagination={{ placement: "top", pageSize: exportPageLimit, showSizeChanger: false }}
columns={columns}
mobileColumnKeys={["ro_number", "date", "owner", "amount", "actions"]}
rowKey="id"
onChange={handleTableChange}
rowSelection={{

View File

@@ -1,4 +1,4 @@
import { Button, Card, Input, Space, Table } from "antd";
import { Button, Card, Input, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -17,6 +17,7 @@ import JobsExportAllButton from "../jobs-export-all-button/jobs-export-all-butto
import JobMarkSelectedExported from "../jobs-mark-selected-exported/jobs-mark-selected-exported";
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -209,11 +210,12 @@ export function AccountingReceivablesTableComponent({ bodyshop, loading, jobs, r
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
dataSource={dataSource}
pagination={{ placement: "top", pageSize: exportPageLimit, showSizeChanger: false }}
columns={columns}
mobileColumnKeys={["ro_number", "status", "owner", "clm_total", "actions"]}
rowKey="id"
onChange={handleTableChange}
rowSelection={{

View File

@@ -1,5 +1,5 @@
import { useState } from "react";
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { alphaSort } from "../../utils/sorters";
import { DateTimeFormatter } from "../../utils/DateFormatter";
import { useTranslation } from "react-i18next";
@@ -62,11 +62,12 @@ export default function AuditTrailListComponent({ loading, data }) {
};
return (
<Table
<ResponsiveTable
{...formItemLayout}
loading={loading}
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={[" created", "operation", " old_val", "useremail"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}

View File

@@ -1,4 +1,4 @@
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { DateTimeFormatter } from "../../utils/DateFormatter";
@@ -47,11 +47,12 @@ export default function EmailAuditTrailListComponent({ loading, data }) {
};
return (
<Table
<ResponsiveTable
{...formItemLayout}
loading={loading}
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={[" created", "useremail"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Form, Input, Table } from "antd";
import { Form, Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
@@ -108,7 +109,14 @@ export default function BillFormLinesExtended({ lineData, discount, form, respon
<Form.Item noStyle name="billlineskeys">
<button onClick={() => console.log(form.getFieldsValue())}>form</button>
<Input onChange={(e) => setSearch(e.target.value)} allowClear />
<Table pagination={false} size="small" columns={columns} rowKey="id" dataSource={data} />
<ResponsiveTable
pagination={false}
size="small"
columns={columns}
mobileColumnKeys={["line_desc", "oem_partno", "part_type", "act_price"]}
rowKey="id"
dataSource={data}
/>
</Form.Item>
);
}

View File

@@ -1,5 +1,5 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
import { Button, Card, Checkbox, Input, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
@@ -18,6 +18,7 @@ import BillDetailEditReturnComponent from "../bill-detail-edit/bill-detail-edit-
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockerWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
const mapStateToProps = createStructuredSelector({
@@ -237,12 +238,13 @@ export function BillsListTableComponent({
</Space>
}
>
<Table
<ResponsiveTable
loading={billsQuery.loading}
scroll={{
x: true // y: "50rem"
}}
columns={columns}
mobileColumnKeys={["vendorname", "invoice_number", "date", "total", "actions"]}
rowKey="id"
dataSource={hasBillsAccess ? filteredBills : []}
onChange={handleTableChange}

View File

@@ -3,7 +3,8 @@ import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
import { useQuery } from "@apollo/client/react";
import queryString from "query-string";
import { useLocation, useNavigate } from "react-router-dom";
import { Input, Table } from "antd";
import { Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
import AlertComponent from "../alert/alert.component";
@@ -79,7 +80,7 @@ export default function BillsVendorsList() {
: (data && data.vendors) || [];
return (
<Table
<ResponsiveTable
loading={loading}
title={() => {
return (
@@ -91,6 +92,7 @@ export default function BillsVendorsList() {
dataSource={dataSource}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["name", "cost_center", "city"]}
rowKey="id"
onChange={handleTableChange}
rowSelection={{

View File

@@ -1,4 +1,5 @@
import { Card, Input, Table } from "antd";
import { Card, Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -103,10 +104,11 @@ export default function ContractsCarsComponent({ loading, data, selectedCarId, h
/>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["status", "fleetnumber", "readiness", "year"]}
rowKey="id"
dataSource={filteredData}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Card, Input, Table } from "antd";
import { Card, Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -127,10 +128,11 @@ export default function ContractsJobsComponent({ loading, data, selectedJob, han
/>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top", defaultPageSize: pageLimit, defaultCurrent: defaultCurrent }}
columns={columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle", "plate_no"]}
rowKey="id"
dataSource={filteredData}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { useLazyQuery } from "@apollo/client/react";
import { Button, Form, Modal, Table } from "antd";
import { Button, Form, Modal } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -64,7 +65,7 @@ export function ContractsFindModalContainer({ contractFinderModal, toggleModalVi
{t("general.labels.search")}
</Button>
{error && <AlertComponent type="error" title={JSON.stringify(error)} />}
<Table
<ResponsiveTable
loading={loading}
columns={[
{
@@ -124,6 +125,7 @@ export function ContractsFindModalContainer({ contractFinderModal, toggleModalVi
render: (text, record) => <DateTimeFormatter>{record.actualreturn}</DateTimeFormatter>
}
]}
mobileColumnKeys={["agreementnumber", "job.ro_number", "driver_ln", "status"]}
rowKey="id"
dataSource={data?.cccontracts}
/>

View File

@@ -1,5 +1,5 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -14,6 +14,7 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { pageLimit } from "../../utils/config";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -170,13 +171,14 @@ export function ContractsList({ bodyshop, loading, contracts, refetch, total, se
}
>
<ContractsFindModalContainer />
<Table
<ResponsiveTable
loading={loading}
scroll={{
x: "50%" //y: "40rem"
}}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(page || 1, 10), total: total }}
columns={columns}
mobileColumnKeys={["agreementnumber", "driver_ln", "status", "scheduledreturn"]}
rowKey="id"
dataSource={contracts}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Card, Table } from "antd";
import { Card } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { Link, useLocation, useNavigate } from "react-router-dom";
@@ -73,10 +74,11 @@ export default function CourtesyCarContractListComponent({ contracts, totalContr
return (
<Card title={t("menus.header.courtesycars-contracts")}>
<Table
<ResponsiveTable
scroll={{ x: true }}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(page || 1), total: totalContracts }}
columns={columns}
mobileColumnKeys={["agreementnumber", "driver_ln", "status", "job.ro_number"]}
rowKey="id"
dataSource={contracts}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { SyncOutlined, WarningFilled } from "@ant-design/icons";
import { Button, Card, Dropdown, Input, Space, Table, Tooltip } from "antd";
import { Button, Card, Dropdown, Input, Space, Tooltip } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import dayjs from "../../utils/day";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -275,10 +276,11 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["status", "fleetnumber", "vin", "readiness"]}
rowKey="id"
dataSource={tableData}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Table } from "antd";
import { Button, Card } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -86,10 +87,11 @@ export default function CsiResponseListPaginated({ refetch, loading, responses,
return (
<Card extra={<Button onClick={() => refetch()} icon={<SyncOutlined />} />}>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(state.page || 1), total: total }}
columns={columns}
mobileColumnKeys={["ro_number", "owner_name", "completedon"]}
rowKey="id"
dataSource={responses}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Card, Table, Tag } from "antd";
import { Card, Tag } from "antd";
import ResponsiveTable from "../../responsive-table/responsive-table.component";
import axios from "axios";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -182,10 +183,11 @@ export default function JobLifecycleDashboardComponent({ data, bodyshop, ...card
</div>
</Card>
<Card style={{ marginTop: "5px" }} type="inner" title={t("job_lifecycle.titles.top_durations")}>
<Table
<ResponsiveTable
size="small"
pagination={false}
columns={columns}
mobileColumnKeys={["status", "humanReadable", "averageHumanReadable", "statusCount"]}
rowKey={(record) => record.status}
dataSource={lifecycleData.summations.sort((a, b) => b.value - a.value).slice(0, 3)}
/>

View File

@@ -1,4 +1,5 @@
import { Card, Input, Space, Table, Typography } from "antd";
import { Card, Input, Space, Typography } from "antd";
import ResponsiveTable from "../../responsive-table/responsive-table.component";
import axios from "axios";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -104,30 +105,31 @@ export default function DashboardMonthlyJobCosting({ data, ...cardProps }) {
>
<LoadingSkeleton loading={loading}>
<div style={{ height: "100%" }}>
<Table
<ResponsiveTable
onChange={handleTableChange}
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={["cost_center", "sales", "costs", "gpdollars"]}
scroll={{ x: true, y: "calc(100% - 4em)" }}
rowKey="id"
style={{ height: "100%" }}
dataSource={filteredData}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Typography.Title level={4}>{t("general.labels.totals")}</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>
{Dinero(costingData?.allSummaryData && costingData.allSummaryData.totalSales).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>
{Dinero(costingData?.allSummaryData && costingData.allSummaryData.totalCost).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>
{Dinero(costingData?.allSummaryData && costingData.allSummaryData.gpdollars).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell></ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
)}
/>
</div>

View File

@@ -1,5 +1,6 @@
import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined } from "@ant-design/icons";
import { Card, Space, Switch, Table, Tooltip, Typography } from "antd";
import { Card, Space, Switch, Tooltip, Typography } from "antd";
import ResponsiveTable from "../../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -359,10 +360,11 @@ export default function DashboardScheduledDeliveryToday({ data, ...cardProps })
{...cardProps}
>
<div style={{ height: "100%" }}>
<Table
<ResponsiveTable
onChange={handleTableChange}
pagination={false}
columns={isTvModeScheduledDelivery ? tvColumns : columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
scroll={{ x: true, y: "calc(100% - 2em)" }}
rowKey="id"
style={{ height: "85%" }}

View File

@@ -1,5 +1,6 @@
import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined } from "@ant-design/icons";
import { Card, Space, Switch, Table, Tooltip, Typography } from "antd";
import { Card, Space, Switch, Tooltip, Typography } from "antd";
import ResponsiveTable from "../../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -364,10 +365,11 @@ export default function DashboardScheduledInToday({ data, ...cardProps }) {
{...cardProps}
>
<div style={{ height: "100%" }}>
<Table
<ResponsiveTable
onChange={handleTableChange}
pagination={false}
columns={isTvModeScheduledIn ? tvColumns : columns}
mobileColumnKeys={["ro_number", "owner", "vehicle", "start"]}
scroll={{ x: true, y: "calc(100% - 2em)" }}
rowKey="id"
style={{ height: "85%" }}

View File

@@ -1,5 +1,6 @@
import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined } from "@ant-design/icons";
import { Card, Space, Switch, Table, Tooltip, Typography } from "antd";
import { Card, Space, Switch, Tooltip, Typography } from "antd";
import ResponsiveTable from "../../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -359,10 +360,11 @@ export default function DashboardScheduledOutToday({ data, ...cardProps }) {
{...cardProps}
>
<div style={{ height: "100%" }}>
<Table
<ResponsiveTable
onChange={handleTableChange}
pagination={false}
columns={isTvModeScheduledOut ? tvColumns : columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
scroll={{ x: true, y: "calc(100% - 2em)" }}
rowKey="id"
style={{ height: "85%" }}

View File

@@ -1,5 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Form, Input, Table } from "antd";
import { Button, Card, Form, Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -78,7 +79,7 @@ export function DmsAllocationsSummaryAp({ socket, bodyshop, billids, title }) {
dataIndex: "Lines",
key: "Lines",
render: (text, record) => (
<table style={{ tableLayout: "auto", width: "100%" }}>
<ResponsiveTable style={{ tableLayout: "auto", width: "100%" }}>
<tr>
<th>{t("bills.fields.invoice_number")}</th>
<th>{t("bodyshop.fields.dms.dms_acctnumber")}</th>
@@ -91,7 +92,7 @@ export function DmsAllocationsSummaryAp({ socket, bodyshop, billids, title }) {
<td>{l.Amount}</td>
</tr>
))}
</table>
</ResponsiveTable>
)
}
];
@@ -115,9 +116,10 @@ export function DmsAllocationsSummaryAp({ socket, bodyshop, billids, title }) {
/>
}
>
<Table
<ResponsiveTable
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={["status", "reference", "Lines"]}
rowKey={(record) => `${record.InvoiceNumber}${record.Account}`}
dataSource={allocationsSummary}
locale={{ emptyText: t("dms.labels.refreshallocations") }}

View File

@@ -1,4 +1,5 @@
import { Alert, Button, Card, Table, Typography } from "antd";
import { Alert, Button, Card, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { SyncOutlined } from "@ant-design/icons";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -116,9 +117,10 @@ export function DmsAllocationsSummary({ mode, socket, bodyshop, jobId, title, on
<Alert type="warning" title={t("jobs.labels.dms.disablebillwip")} />
)}
<Table
<ResponsiveTable
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={["center", "sale", "cost", "sale_dms_acctnumber"]}
rowKey="center"
dataSource={allocationsSummary}
locale={{ emptyText: t("dms.labels.refreshallocations") }}
@@ -135,15 +137,17 @@ export function DmsAllocationsSummary({ mode, socket, bodyshop, jobId, title, on
const hasNonZeroSaleTotal = totals.totalSale.getAmount() !== 0;
return (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Typography.Title level={4}>{t("general.labels.totals")}</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>{hasNonZeroSaleTotal ? totals.totalSale.toFormat() : null}</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell />
<Table.Summary.Cell />
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>
{hasNonZeroSaleTotal ? totals.totalSale.toFormat() : null}
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
</ResponsiveTable.Summary.Row>
);
}}
/>

View File

@@ -1,4 +1,5 @@
import { Alert, Button, Card, Table, Tabs, Typography } from "antd";
import { Alert, Button, Card, Tabs, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { SyncOutlined } from "@ant-design/icons";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -261,9 +262,10 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title, onAllocat
into taxable / non-taxable segments.
</Typography.Paragraph>
<Table
<ResponsiveTable
pagination={false}
columns={roggColumns}
mobileColumnKeys={["jobNo", "opCode", "breakOut", "itemType"]}
rowKey="key"
dataSource={roggRows}
locale={{ emptyText: "No ROGOG lines would be generated." }}
@@ -286,19 +288,23 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title, onAllocat
const hasCostTotal = Number(roggTotals.totalDlrCost) !== 0;
return (
<Table.Summary.Row>
<Table.Summary.Cell index={0}>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell index={0}>
<Typography.Title level={5}>{t("general.labels.totals")}</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell index={1} />
<Table.Summary.Cell index={2} />
<Table.Summary.Cell index={3} />
<Table.Summary.Cell index={4} />
<Table.Summary.Cell index={5} />
<Table.Summary.Cell index={6} />
<Table.Summary.Cell index={7}>{hasCustTotal ? roggTotals.totalCustPrice : null}</Table.Summary.Cell>
<Table.Summary.Cell index={8}>{hasCostTotal ? roggTotals.totalDlrCost : null}</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell index={1} />
<ResponsiveTable.Summary.Cell index={2} />
<ResponsiveTable.Summary.Cell index={3} />
<ResponsiveTable.Summary.Cell index={4} />
<ResponsiveTable.Summary.Cell index={5} />
<ResponsiveTable.Summary.Cell index={6} />
<ResponsiveTable.Summary.Cell index={7}>
{hasCustTotal ? roggTotals.totalCustPrice : null}
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell index={8}>
{hasCostTotal ? roggTotals.totalDlrCost : null}
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
);
}}
/>
@@ -313,9 +319,10 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title, onAllocat
<Typography.Paragraph type="secondary" style={{ marginBottom: 8 }}>
This mirrors the shell that would be sent for ROLABOR when all financials are carried in GOG.
</Typography.Paragraph>
<Table
<ResponsiveTable
pagination={false}
columns={rolaborColumns}
mobileColumnKeys={["jobNo", "opCode", "breakOut", "itemType"]}
rowKey="key"
dataSource={rolaborRows}
locale={{ emptyText: "No ROLABOR lines would be generated." }}

View File

@@ -1,5 +1,6 @@
import { useLazyQuery } from "@apollo/client/react";
import { Button, Input, Modal, Table } from "antd";
import { Button, Input, Modal } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -60,7 +61,7 @@ export function DmsCdkVehicles({ form, job }) {
okButtonProps={{ disabled: !selectedModel }}
>
{error && <AlertComponent title={error.message} type="error" />}
<Table
<ResponsiveTable
title={() => (
<Input.Search
onSearch={(val) => callSearch({ variables: { search: val } })}
@@ -69,6 +70,7 @@ export function DmsCdkVehicles({ form, job }) {
/>
)}
columns={columns}
mobileColumnKeys={["make", "model", "makecode", "modelcode"]}
loading={loading}
rowKey="id"
dataSource={data ? data.search_dms_vehicles : []}

View File

@@ -1,4 +1,5 @@
import { Button, Checkbox, Col, Table } from "antd";
import { Button, Checkbox, Col } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -72,7 +73,7 @@ export default function CDKCustomerSelector({ bodyshop, socket }) {
return (
<Col span={24}>
<Table
<ResponsiveTable
title={() => (
<div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
<Button onClick={onUseSelected} disabled={!selectedCustomer}>
@@ -86,6 +87,7 @@ export default function CDKCustomerSelector({ bodyshop, socket }) {
)}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["id", "vinOwner", "name1", "address"]}
rowKey={rowKey}
dataSource={customerList}
rowSelection={{

View File

@@ -1,4 +1,5 @@
import { Button, Checkbox, Col, Table } from "antd";
import { Button, Checkbox, Col } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -78,7 +79,7 @@ export default function FortellisCustomerSelector({ bodyshop, jobid, socket }) {
return (
<Col span={24}>
<Table
<ResponsiveTable
title={() => (
<div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
<Button onClick={onUseSelected} disabled={!selectedCustomer}>
@@ -92,6 +93,7 @@ export default function FortellisCustomerSelector({ bodyshop, jobid, socket }) {
)}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["id", "vinOwner", "firstName", "address"]}
rowKey={(r) => r.customerId}
dataSource={customerList}
rowSelection={{

View File

@@ -1,4 +1,5 @@
import { Button, Col, Table } from "antd";
import { Button, Col } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -66,7 +67,7 @@ export default function PBSCustomerSelector({ bodyshop, socket }) {
return (
<Col span={24}>
<Table
<ResponsiveTable
title={() => (
<div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
<Button onClick={onUseSelected} disabled={!selectedCustomer}>
@@ -80,6 +81,7 @@ export default function PBSCustomerSelector({ bodyshop, socket }) {
)}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["ContactId", "name1", "address"]}
rowKey={(r) => r.ContactId}
dataSource={customerList}
rowSelection={{

View File

@@ -1,4 +1,5 @@
import { Alert, Button, Checkbox, message, Modal, Space, Table } from "antd";
import { Alert, Button, Checkbox, message, Modal, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -195,8 +196,8 @@ export default function RRCustomerSelector({
description={
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
<div>
We created the Repair Order. Please validate the totals and taxes in the DMS system. When done,
click <strong>Finished</strong> to finalize and mark this export as complete.
We created the Repair Order. Please validate the totals and taxes in the DMS system. When done, click{" "}
<strong>Finished</strong> to finalize and mark this export as complete.
</div>
<div>
<Space>
@@ -215,14 +216,8 @@ export default function RRCustomerSelector({
}
return (
<Modal
open={open}
onCancel={handleClose}
footer={null}
width={800}
title={t("dms.selectCustomer")}
>
<Table
<Modal open={open} onCancel={handleClose} footer={null} width={800} title={t("dms.selectCustomer")}>
<ResponsiveTable
title={() => (
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
{/* Open RO limit banner */}
@@ -304,6 +299,7 @@ export default function RRCustomerSelector({
)}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["custNo", "vinOwner", "name", "address"]}
rowKey={(r) => r.custNo}
dataSource={customerList}
rowSelection={{

View File

@@ -1,5 +1,6 @@
import { ReloadOutlined } from "@ant-design/icons";
import { Alert, Button, Form, Input, InputNumber, Modal, Radio, Select, Space, Table, Typography } from "antd";
import { Alert, Button, Form, Input, InputNumber, Modal, Radio, Select, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useMemo, useState } from "react";
// Simple customer selector table
@@ -26,7 +27,14 @@ function CustomerSelectorTable({ customers, onSelect, isSubmitting }) {
return (
<div>
<Table columns={columns} dataSource={customers} rowKey="custNo" pagination={false} size="small" />
<ResponsiveTable
columns={columns}
mobileColumnKeys={["name", "select", "custNo", "vinOwner"]}
dataSource={customers}
rowKey="custNo"
pagination={false}
size="small"
/>
<div style={{ marginTop: 16, display: "flex", gap: 8 }}>
<Button
type="primary"

View File

@@ -1,5 +1,5 @@
import { EditFilled, FileAddFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -10,6 +10,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter";
import InventoryBillRo from "../inventory-bill-ro/inventory-bill-ro.component";
import InventoryLineDelete from "../inventory-line-delete/inventory-line-delete.component";
import { pageLimit } from "../../utils/config";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
@@ -185,10 +186,11 @@ export function JobsList({ refetch, loading, jobs, total, setInventoryUpsertCont
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(page || 1), total: total }}
columns={columns}
mobileColumnKeys={["line_desc", "actual_price", "consumedbyjob", "actions"]}
rowKey="id"
dataSource={jobs}
onChange={handleTableChange}

View File

@@ -1,6 +1,7 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Col, Row, Table, Tag } from "antd";
import { Button, Card, Col, Row, Tag } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -163,12 +164,24 @@ export function JobAuditTrail({ bodyshop, jobId }) {
/>
}
>
<Table loading={loading} columns={columns} rowKey="id" dataSource={data ? data.audit_trail : []} />
<ResponsiveTable
loading={loading}
columns={columns}
mobileColumnKeys={["status", "created", "useremail", "operation"]}
rowKey="id"
dataSource={data ? data.audit_trail : []}
/>
</Card>
</Col>
<Col span={24}>
<Card title={t("jobs.labels.emailaudit")}>
<Table loading={loading} columns={emailColumns} rowKey="id" dataSource={data ? data.email_audit_trail : []} />
<ResponsiveTable
loading={loading}
columns={emailColumns}
mobileColumnKeys={["status", "created", "useremail", "operation"]}
rowKey="id"
dataSource={data ? data.email_audit_trail : []}
/>
</Card>
</Col>
</Row>

View File

@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { Alert, Card, Table } from "antd";
import { Alert, Card } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { t } from "i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -68,7 +69,15 @@ export function JobCloseRGuardPpd({ job, warningCallback }) {
return (
<Card title={t("jobs.labels.ppdnotexported")}>
<Table dataSource={linesWithPPD} columns={columns} pagination={false} rowKey="id" bordered size="small" />
<ResponsiveTable
dataSource={linesWithPPD}
columns={columns}
mobileColumnKeys={["line_desc", "ppd", "act_price", "act_price_before_ppc"]}
pagination={false}
rowKey="id"
bordered
size="small"
/>
{linesWithPPD.length > 0 && (
<Alert style={{ margin: "8px 0px" }} type="warning" title={t("jobs.labels.outstanding_ppd")} />
)}

View File

@@ -1,6 +1,7 @@
import { useEffect } from "react";
import { Alert, Card, Table } from "antd";
import { Alert, Card } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { t } from "i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -62,7 +63,15 @@ export function JobCloseRGuardSublet({ job, warningCallback }) {
return (
<Card title={t("jobs.labels.subletsnotcompleted")}>
<Table dataSource={subletsNotDone} columns={columns} pagination={false} rowKey="id" bordered size="small" />
<ResponsiveTable
dataSource={subletsNotDone}
columns={columns}
mobileColumnKeys={["line_desc", "act_price", "part_qty", "notes"]}
pagination={false}
rowKey="id"
bordered
size="small"
/>
{subletsNotDone.length > 0 && (
<Alert style={{ margin: "8px 0px" }} type="warning" title={t("jobs.labels.outstanding_sublets")} />
)}

View File

@@ -1,4 +1,5 @@
import { Input, Space, Table, Typography } from "antd";
import { Input, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
@@ -65,7 +66,7 @@ export default function JobCostingPartsTable({ data, summaryData }) {
return (
<div>
<Table
<ResponsiveTable
title={() => {
return (
<Space wrap>
@@ -87,18 +88,19 @@ export default function JobCostingPartsTable({ data, summaryData }) {
onChange={handleTableChange}
pagination={{ placement: "top", defaultPageSize: pageLimit }}
columns={columns}
mobileColumnKeys={["cost_center", "sales", "costs", "gpdollars", "gppercent"]}
rowKey="id"
dataSource={filteredData}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Typography.Title level={4}>{t("general.labels.totals")}</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>{Dinero(summaryData.totalSales).toFormat()}</Table.Summary.Cell>
<Table.Summary.Cell>{Dinero(summaryData.totalCost).toFormat()}</Table.Summary.Cell>
<Table.Summary.Cell>{Dinero(summaryData.gpdollars).toFormat()}</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{Dinero(summaryData.totalSales).toFormat()}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{Dinero(summaryData.totalCost).toFormat()}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{Dinero(summaryData.gpdollars).toFormat()}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell></ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
)}
/>
</div>

View File

@@ -1,4 +1,4 @@
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import JobLineNotePopup from "../job-line-note-popup/job-line-note-popup.component";
import PartsStatusPie from "../parts-status-pie/parts-status-pie.component";
@@ -101,7 +101,12 @@ function JobDetailCardsPartsComponent({ loading, data, jobRO }) {
<div>
<CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}>
<PartsStatusPie joblines_status={joblines_status} />
<Table rowKey="id" columns={columns} dataSource={filteredJobLines || []} />
<ResponsiveTable
rowKey="id"
columns={columns}
mobileColumnKeys={["status", "line_desc", "part_type", "part_qty"]}
dataSource={filteredJobLines || []}
/>
</CardTemplate>
</div>
);

View File

@@ -11,7 +11,8 @@ import {
import { PageHeader } from "@ant-design/pro-layout";
import { useMutation } from "@apollo/client/react";
import { gql } from "@apollo/client";
import { Button, Dropdown, Input, Modal, Select, Space, Table, Tag, Typography } from "antd";
import { Button, Dropdown, Input, Modal, Select, Space, Tag, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import axios from "axios";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -688,8 +689,9 @@ export function JobLinesComponent({
}
/>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["status", "line_desc", "actions", "line_no"]}
rowKey="id"
loading={loading}
pagination={false}

View File

@@ -1,6 +1,7 @@
import { useQuery } from "@apollo/client/react";
import { gql } from "@apollo/client";
import { Badge, Card, Space, Table, Tag } from "antd";
import { Badge, Card, Space, Tag } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import axios from "axios";
import { isEmpty } from "lodash";
import { useCallback, useEffect, useState } from "react";
@@ -311,12 +312,13 @@ export function JobLifecycleComponent({ bodyshop, job, statuses }) {
</>
}
>
<Table
<ResponsiveTable
style={{
overflow: "auto",
width: "100%"
}}
columns={columns}
mobileColumnKeys={["value", "start", "start_readable", "end"]}
dataSource={lifecycleData.lifecycle}
rowKey="start"
/>

View File

@@ -1,5 +1,6 @@
import { EditFilled } from "@ant-design/icons";
import { Button, Card, Space, Table } from "antd";
import { Button, Card, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -186,8 +187,9 @@ export function JobPayments({ job, bodyshop, setPaymentContext, setCardPaymentCo
</Space>
}
>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["date", "amount", "actions", "payer"]}
rowKey="id"
pagination={false}
onChange={handleTableChange}
@@ -199,18 +201,18 @@ export function JobPayments({ job, bodyshop, setPaymentContext, setCardPaymentCo
expandedRowRender: (record) => <PaymentExpandedRowComponent record={record} bodyshop={bodyshop} />
}}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("payments.labels.totalpayments")}</strong>
</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell>
<strong>{total.toFormat()}</strong>
</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell />
<Table.Summary.Cell />
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
</ResponsiveTable.Summary.Row>
)}
/>
</Card>

View File

@@ -1,4 +1,5 @@
import { Checkbox, Table, Typography } from "antd";
import { Checkbox, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
@@ -79,11 +80,12 @@ export default function JobReconciliationBillsTable({ billLineState, invoiceLine
return (
<div>
<Typography.Title level={4}>{t("bills.labels.bills")}</Typography.Title>
<Table
<ResponsiveTable
pagination={false}
size="small"
scroll={{ y: "60vh" }}
columns={columns}
mobileColumnKeys={["line_desc", "from", "actual_price", "actual_cost"]}
rowKey="id"
dataSource={invoiceLineData}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Table, Typography } from "antd";
import { Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
@@ -96,9 +97,10 @@ export default function JobReconcilitionPartsTable({ jobLineState, jobLineData }
return (
<div>
<Typography.Title level={4}>{t("jobs.labels.lines")}</Typography.Title>
<Table
<ResponsiveTable
pagination={false}
columns={columns}
mobileColumnKeys={["status", "line_desc", "total", "oem_partno"]}
size="small"
scroll={{ y: "60vh" }}
rowKey="id"

View File

@@ -1,4 +1,5 @@
import { Space, Table } from "antd";
import { Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -104,8 +105,9 @@ export default function JobTotalsTableLabor({ job }) {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
return (
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["total", "profitcenter_labor", "rate", "mod_lb_hrs"]}
rowKey="id"
pagination={false}
onChange={handleTableChange}
@@ -115,29 +117,29 @@ export default function JobTotalsTableLabor({ job }) {
}}
summary={() => (
<>
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("jobs.labels.labor_rates_subtotal")}</strong>
</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell>
{(job.job_totals.rates.mapa.hours + job.job_totals.rates.mash.hours).toFixed(1)}
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
{InstanceRenderManager({
imex: null,
rome: (
<>
<Table.Summary.Cell />
<Table.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
</>
)
})}
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
<strong>{Dinero(job.job_totals.rates.rates_subtotal).toFormat()}</strong>
</Table.Summary.Cell>
</Table.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Space>
{t("jobs.labels.mapa")}
{InstanceRenderManager({
@@ -156,34 +158,34 @@ export default function JobTotalsTableLabor({ job }) {
})
})}
</Space>
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
<CurrencyFormatter>{job.job_totals.rates.mapa.rate}</CurrencyFormatter>
</Table.Summary.Cell>
<Table.Summary.Cell>{job.job_totals.rates.mapa.hours.toFixed(1)}</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{job.job_totals.rates.mapa.hours.toFixed(1)}</ResponsiveTable.Summary.Cell>
{InstanceRenderManager({
imex: (
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mapa.total).toFormat()}
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
),
rome: (
<>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mapa.base).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mapa.adjustment).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mapa.total).toFormat()}
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
</>
)
})}
</Table.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Space wrap>
{t("jobs.labels.mash")}
{InstanceRenderManager({
@@ -202,51 +204,51 @@ export default function JobTotalsTableLabor({ job }) {
})
})}
</Space>
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
<CurrencyFormatter>{job.job_totals.rates.mash.rate}</CurrencyFormatter>
</Table.Summary.Cell>
<Table.Summary.Cell>{job.job_totals.rates.mash.hours.toFixed(1)}</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{job.job_totals.rates.mash.hours.toFixed(1)}</ResponsiveTable.Summary.Cell>
{InstanceRenderManager({
imex: (
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mash.total).toFormat()}
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
),
rome: (
<>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mash.base).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mash.adjustment).toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.rates.mash.total).toFormat()}
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
</>
)
})}
</Table.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("jobs.labels.rates_subtotal")}</strong>
</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell />
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
{InstanceRenderManager({
imex: null,
rome: (
<>
<Table.Summary.Cell />
<Table.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
</>
)
})}
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
<strong>{Dinero(job.job_totals.rates.subtotal).toFormat()}</strong>
</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
</>
)}
/>

View File

@@ -1,4 +1,4 @@
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -65,8 +65,9 @@ export default function JobTotalsTableOther({ job }) {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
return (
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["total", "key"]}
rowKey="key"
pagination={false}
onChange={handleTableChange}
@@ -76,24 +77,24 @@ export default function JobTotalsTableOther({ job }) {
}}
summary={() => (
<>
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("jobs.labels.additionaltotal")}</strong>
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
<strong>{Dinero(job.job_totals.additional.total).toFormat()}</strong>
</Table.Summary.Cell>
</Table.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("jobs.labels.subletstotal")}</strong>
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
<strong>{Dinero(job.job_totals.parts.sublets.total).toFormat()}</strong>
</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
</>
)}
/>

View File

@@ -1,4 +1,4 @@
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -64,8 +64,9 @@ export default function JobTotalsTableParts({ job }) {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
return (
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["total", "id"]}
rowKey="id"
pagination={false}
onChange={handleTableChange}
@@ -75,36 +76,38 @@ export default function JobTotalsTableParts({ job }) {
}}
summary={() => (
<>
<Table.Summary.Row>
<Table.Summary.Cell>{t("jobs.labels.prt_dsmk_total")}</Table.Summary.Cell>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>{t("jobs.labels.prt_dsmk_total")}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{Dinero(job.job_totals.parts.parts.prt_dsmk_total).toFormat()}
</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<strong>{t("jobs.labels.partstotal")}</strong>
</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<Table.Summary.Cell align="right">
<ResponsiveTable.Summary.Cell align="right">
<strong>{Dinero(job.job_totals.parts.parts.total).toFormat()}</strong>
</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
{
//TODO:AIO This shoudl only be in the US version. need to verify whether this causes problems for the CA version.
insuranceAdjustments.length > 0 && (
<Table.Summary.Row>
<Table.Summary.Cell colSpan={24}>{t("jobs.labels.profileadjustments")}</Table.Summary.Cell>
</Table.Summary.Row>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell colSpan={24}>
{t("jobs.labels.profileadjustments")}
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
)
}
{insuranceAdjustments.map((adj, idx) => (
<Table.Summary.Row key={idx}>
<Table.Summary.Cell>{t(`jobs.fields.${adj.id.toLowerCase()}`)}</Table.Summary.Cell>
<ResponsiveTable.Summary.Row key={idx}>
<ResponsiveTable.Summary.Cell>{t(`jobs.fields.${adj.id.toLowerCase()}`)}</ResponsiveTable.Summary.Cell>
<Table.Summary.Cell align="right">{adj.amount.toFormat()}</Table.Summary.Cell>
</Table.Summary.Row>
<ResponsiveTable.Summary.Cell align="right">{adj.amount.toFormat()}</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
))}
</>
)}

View File

@@ -1,4 +1,4 @@
import { Table } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
@@ -245,8 +245,9 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
];
return (
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["total", "key"]}
rowKey="key"
showHeader={false}
pagination={false}

View File

@@ -1,5 +1,5 @@
import { DownloadOutlined, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table } from "antd";
import { Button, Card, Input, Space } from "antd";
import axios from "axios";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -9,6 +9,7 @@ import { useNotification } from "../../contexts/Notifications/notificationContex
import { selectPartnerVersion } from "../../redux/application/application.selectors";
import { alphaSort } from "../../utils/sorters";
import { logImEXEvent } from "../../firebase/firebase.utils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -141,10 +142,11 @@ export function JobsAvailableScan({ partnerVersion, refetch }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["cieca_id", "owner", "vehicle", "actions"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}

View File

@@ -1,6 +1,6 @@
import { DeleteFilled, DownloadOutlined, PlusCircleFilled, SyncOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Alert, Button, Card, Input, Space, Table } from "antd";
import { Alert, Button, Card, Input, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -13,6 +13,7 @@ import { TimeAgoFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { logImEXEvent } from "../../firebase/firebase.utils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -209,7 +210,14 @@ export function JobsAvailableComponent({ bodyshop, loading, data, refetch, addJo
</Space>
}
>
<Table loading={loading} columns={columns} rowKey="id" dataSource={availableJobs} onChange={handleTableChange} />
<ResponsiveTable
loading={loading}
columns={columns}
mobileColumnKeys={["cieca_id", "job_id", "ownr_name", "vehicle_info", "actions"]}
rowKey="id"
dataSource={availableJobs}
onChange={handleTableChange}
/>
</Card>
);
}

View File

@@ -1,4 +1,5 @@
import { Card, Input, Table } from "antd";
import { Card, Input } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useContext, useState } from "react";
import { useTranslation } from "react-i18next";
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
@@ -95,11 +96,12 @@ export default function JobsCreateOwnerInfoSearchComponent({ loading, owners })
/>
}
>
<Table
<ResponsiveTable
loading={loading}
scroll={{ x: true }}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["ownr_ln", "ownr_ph1", "ownr_ph2", "ownr_fn"]}
rowKey="id"
dataSource={owners}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { PlusOutlined, SearchOutlined } from "@ant-design/icons";
import { Button, Input, Popover, Table } from "antd";
import { Button, Input, Popover } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import PredefinedVehicles from "./predefined-vehicles.js";
@@ -22,7 +23,7 @@ export default function JobsCreateVehicleInfoPredefined({ disabled, form }) {
const popContent = () => (
<div>
<Table
<ResponsiveTable
size="small"
title={() => <Input.Search onSearch={(value) => setSearch(value)} enterButton />}
dataSource={filteredPredefinedVehicles}
@@ -61,6 +62,7 @@ export default function JobsCreateVehicleInfoPredefined({ disabled, form }) {
)
}
]}
mobileColumnKeys={["make", "model", "select"]}
/>
</div>
);

View File

@@ -1,4 +1,5 @@
import { Card, Input, Space, Table } from "antd";
import { Card, Input, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useContext, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -68,11 +69,12 @@ export default function JobsCreateVehicleInfoSearchComponent({ loading, vehicles
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
scroll={{ x: true }}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["v_vin", "description", "plate"]}
rowKey="id"
dataSource={vehicles}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Checkbox, Divider, Input, Space, Table } from "antd";
import { Button, Checkbox, Divider, Input, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -171,7 +172,7 @@ export default function JobsFindModalComponent({
return (
<div>
<Table
<ResponsiveTable
title={() => (
<div style={{ display: "flex" }}>
{t("jobs.labels.existing_jobs")}
@@ -191,6 +192,7 @@ export default function JobsFindModalComponent({
)}
pagination={{ placement: "bottom" }}
columns={columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
rowKey="id"
loading={jobsListLoading}
dataSource={jobsList}

View File

@@ -1,5 +1,5 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import axios from "axios";
import _ from "lodash";
import queryString from "query-string";
@@ -15,6 +15,7 @@ import { alphaSort, statusSort } from "../../utils/sorters";
import useLocalStorage from "../../utils/useLocalStorage";
import StartChatButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
const mapStateToProps = createStructuredSelector({
@@ -238,7 +239,7 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading || searchLoading}
pagination={
search?.search
@@ -254,6 +255,7 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
}
}
columns={columns}
mobileColumnKeys={["ro_number", "ownr_ln", "status", "vehicle"]}
rowKey="id"
dataSource={search?.search ? openSearchResults : jobs}
onChange={handleTableChange}

View File

@@ -1,6 +1,6 @@
import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined, SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Grid, Input, Space, Table, Tooltip } from "antd";
import { Button, Card, Input, Space, Tooltip } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -16,6 +16,7 @@ import useLocalStorage from "../../utils/useLocalStorage";
import AlertComponent from "../alert/alert.component";
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { OwnerNameDisplayFunction } from "./../owner-name-display/owner-name-display.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
@@ -28,7 +29,6 @@ const mapDispatchToProps = () => ({});
export function JobsList({ bodyshop }) {
const searchParams = queryString.parse(useLocation().search);
const { selected } = searchParams;
const screens = Grid.useBreakpoint();
const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, {
variables: {
statuses: bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"]
@@ -296,15 +296,6 @@ export function JobsList({ bodyshop }) {
// },
];
const scrollMapper = {
xs: true,
sm: true,
md: true,
lg: "100%",
xl: "100%",
xxl: "100%"
};
return (
<Card
id="active-jobs-list"
@@ -323,25 +314,13 @@ export function JobsList({ bodyshop }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ defaultPageSize: 50 }}
columns={columns}
rowKey="id"
dataSource={jobs}
scroll={{
x: screens.xxl
? scrollMapper.xxl
: screens.xl
? scrollMapper.xl
: screens.lg
? scrollMapper.lg
: screens.md
? scrollMapper.md
: screens.sm
? scrollMapper.sm
: scrollMapper.xs
}}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
rowSelection={{
onSelect: (record) => {
handleOnRowClick(record);

View File

@@ -1,5 +1,6 @@
import { AuditOutlined, DeleteFilled, EditFilled, EyeInvisibleFilled, WarningFilled } from "@ant-design/icons";
import { Button, Card, Form, Input, Space, Table } from "antd";
import { Button, Card, Form, Input, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -185,7 +186,14 @@ export function JobNotesComponent({
</Button>
}
>
<Table loading={loading} columns={columns} rowKey="id" dataSource={data} onChange={handleTableChange} />
<ResponsiveTable
loading={loading}
columns={columns}
mobileColumnKeys={["actions", "icons", "type", "text"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}
/>
</Card>
</div>
);

View File

@@ -1,6 +1,6 @@
import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined, SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Grid, Input, Space, Table, Tooltip } from "antd";
import { Button, Card, Input, Space, Tooltip } from "antd";
import queryString from "query-string";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -17,6 +17,7 @@ import useLocalStorage from "../../utils/useLocalStorage";
import AlertComponent from "../alert/alert.component";
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -25,7 +26,6 @@ const mapStateToProps = createStructuredSelector({
export function JobsReadyList({ bodyshop }) {
const searchParams = queryString.parse(useLocation().search);
const { selected } = searchParams;
const screens = Grid.useBreakpoint();
const readyStatuses = useMemo(() => {
if (bodyshop.md_ro_statuses.ready_statuses) return bodyshop.md_ro_statuses.ready_statuses;
@@ -280,15 +280,6 @@ export function JobsReadyList({ bodyshop }) {
// },
];
const scrollMapper = {
xs: true,
sm: true,
md: true,
lg: "100%",
xl: "100%",
xxl: "100%"
};
return (
<Card
title={t("titles.bc.jobs-ready")}
@@ -307,25 +298,13 @@ export function JobsReadyList({ bodyshop }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ defaultPageSize: pageLimit }}
columns={columns}
rowKey="id"
dataSource={jobs}
scroll={{
x: screens.xxl
? scrollMapper.xxl
: screens.xl
? scrollMapper.xl
: screens.lg
? scrollMapper.lg
: screens.md
? scrollMapper.md
: screens.sm
? scrollMapper.sm
: scrollMapper.xs
}}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
rowSelection={{
onSelect: (record) => {
handleOnRowClick(record);

View File

@@ -1,5 +1,6 @@
import { EditFilled } from "@ant-design/icons";
import { Alert, Card, Col, Row, Space, Table, Typography } from "antd";
import { Alert, Card, Col, Row, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -196,8 +197,9 @@ export function LaborAllocationsTable({
<Row gutter={[16, 16]}>
<Col span={24}>
<Card title={t("jobs.labels.laborallocations")}>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["line_desc", "total", "cost_center", "hrs_claimed"]}
rowKey={(record) => `${record.cost_center} ${record.mod_lbr_ty}`}
pagination={false}
onChange={handleTableChange}
@@ -215,16 +217,22 @@ export function LaborAllocationsTable({
x: true
}}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Typography.Title level={4} style={{ margin: 0, lineHeight: 1 }}>
{t("general.labels.totals")}
</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell align="right">{summary.hrs_total.toFixed(1)}</Table.Summary.Cell>
<Table.Summary.Cell align="right">{summary.hrs_claimed.toFixed(1)}</Table.Summary.Cell>
<Table.Summary.Cell align="right">{summary.adjustments.toFixed(1)}</Table.Summary.Cell>
<Table.Summary.Cell align="right">
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{summary.hrs_total.toFixed(1)}
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{summary.hrs_claimed.toFixed(1)}
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
{summary.adjustments.toFixed(1)}
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell align="right">
<Typography.Text
style={{
fontWeight: "bold",
@@ -233,8 +241,8 @@ export function LaborAllocationsTable({
>
{(Math.abs(summary.difference) < 0.05 ? 0 : summary.difference).toFixed(1)}
</Typography.Text>
</Table.Summary.Cell>
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
)}
/>
</Card>
@@ -242,8 +250,9 @@ export function LaborAllocationsTable({
{convertedLines && convertedLines.length > 0 && (
<Col span={24}>
<Card title={t("jobs.labels.convertedtolabor")}>
<Table
<ResponsiveTable
columns={convertedTableCols}
mobileColumnKeys={["line_desc", "total", "cost_center", "hrs_claimed"]}
rowKey="id"
pagination={false}
dataSource={hasTimeTicketAccess ? convertedLines : []}

View File

@@ -1,4 +1,5 @@
import { Alert, Button, Card, Col, Row, Space, Table, Typography } from "antd";
import { Alert, Button, Card, Col, Row, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { SyncOutlined } from "@ant-design/icons";
import axios from "axios";
import _ from "lodash";
@@ -251,8 +252,9 @@ export function PayrollLaborAllocationsTable({
</Space>
}
>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["line_desc", "employeeid", "mod_lbr_ty", "rate"]}
rowKey={(record) => `${record.employeeid} ${record.mod_lbr_ty}`}
pagination={false}
onChange={handleTableChange}
@@ -270,16 +272,16 @@ export function PayrollLaborAllocationsTable({
})
}}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>
<Typography.Title level={4}>{t("general.labels.totals")}</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
<Table.Summary.Cell>{summary.hrs_total.toFixed(5)}</Table.Summary.Cell>
<Table.Summary.Cell>{summary.hrs_claimed.toFixed(5)}</Table.Summary.Cell>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell></ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{summary.hrs_total.toFixed(5)}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{summary.hrs_claimed.toFixed(5)}</ResponsiveTable.Summary.Cell>
<Table.Summary.Cell>{summary.difference.toFixed(5)}</Table.Summary.Cell>
</Table.Summary.Row>
<ResponsiveTable.Summary.Cell>{summary.difference.toFixed(5)}</ResponsiveTable.Summary.Cell>
</ResponsiveTable.Summary.Row>
)}
/>
</Card>
@@ -287,8 +289,9 @@ export function PayrollLaborAllocationsTable({
{convertedLines && convertedLines.length > 0 && (
<Col span={24}>
<Card title={t("jobs.labels.convertedtolabor")}>
<Table
<ResponsiveTable
columns={convertedTableCols}
mobileColumnKeys={["line_desc", "employeeid", "mod_lbr_ty", "rate"]}
rowKey="id"
pagination={false}
dataSource={convertedLines}

View File

@@ -7,7 +7,7 @@ export default function LayoutFormRow({
children,
grow = false,
noDivider = false,
gutter = [16, 16],
gutter = [16, 16], // Responsive gutter: horizontal, vertical
rowProps,
// Optional overrides if you ever need per-section customization
@@ -63,30 +63,60 @@ export default function LayoutFormRow({
}
const count = items.length;
const spanFor = (min) => Math.max(min, Math.floor(24 / count));
// Mobile-first: stack on xs
const baseCol = {
xs: { span: 24 },
sm: { span: grow ? spanFor(12) : 12 },
md: { span: grow ? spanFor(8) : 8 },
lg: { span: grow ? spanFor(6) : 6 },
xl: { span: grow ? spanFor(4) : 4 },
xxl: { span: grow ? spanFor(4) : 4 }
// Modern responsive strategy leveraging Ant Design 6:
// - xs (phone <576px): Always stack vertically
// - sm (tablet 576-768px): 2 columns for better readability
// - md (tablet 768-992px): 3 columns for tablets
// - lg+ (desktop >992px): Dynamic flex-based columns that adapt to screen width
// Target: 1366px → 4 cols, 1920px → 6 cols, 2560px → 8 cols, 4K → capped at 8-9 cols
// Note: xxl uses higher min-width to naturally cap maximum columns
const baseCol = (() => {
if (grow) {
// Grow mode: use flex with reasonable min-widths
return {
xs: 24,
sm: 12, // Fixed 2 cols on small tablets
md: 8, // Fixed 3 cols on large tablets
lg: { flex: `1 1 320px` }, // Dynamic: ~3 cols at 1200px
xl: { flex: `1 1 280px` }, // Dynamic: ~4 cols at 1366px, ~6 cols at 1920px
xxl: { flex: `1 1 380px` } // Dynamic: ~6 cols at 2560px, ~9 cols at 4K (capped)
};
} else {
// Fixed mode: Use flex without grow to maintain uniform widths across rows
// xxl uses larger min-width to cap maximum columns on 4K/ultrawide
const minWidthLg = count <= 2 ? 500 : count === 3 ? 380 : 320; // 3 cols at 1200px
const minWidthXl = count <= 2 ? 480 : count === 3 ? 360 : 280; // 4 cols at 1366px, ~6 at 1920px
const minWidthXxl = count <= 2 ? 500 : count === 3 ? 400 : 380; // ~6 cols at 2560px, ~9 at 4K (natural cap)
return {
xs: 24,
sm: 12, // Fixed 2 columns on tablet
md: count === 1 ? 24 : count === 2 ? 12 : 8, // Fixed 1-3 cols on large tablet
lg: count === 1 ? 24 : { flex: `0 0 ${minWidthLg}px` }, // Fixed width on desktop
xl: count === 1 ? 24 : { flex: `0 0 ${minWidthXl}px` }, // Fixed width on large desktop
xxl: count === 1 ? 24 : { flex: `0 0 ${minWidthXxl}px` } // Fixed width on ultrawide
};
}
})();
const getColPropsForChild = (child) => {
if (!isValidElement(child)) return baseCol;
// Back-compat with old pattern: child.props.span can override Col sizing
// Back-compat: child.props.span can override Col sizing
const spanOverride = child.props?.span;
if (typeof spanOverride === "number") return { span: spanOverride };
if (spanOverride && typeof spanOverride === "object") return spanOverride;
// Optional explicit override: <Field col={{ md:{span:12}, ... }} />
// Explicit override: <Field col={{ md:{span:12}, ... }} />
const colOverride = child.props?.col;
if (colOverride && typeof colOverride === "object") {
return { ...baseCol, ...colOverride };
// Deep merge: allow partial overrides while keeping baseCol defaults
const merged = { ...baseCol };
Object.keys(colOverride).forEach((bp) => {
merged[bp] = typeof colOverride[bp] === "object" ? { ...baseCol[bp], ...colOverride[bp] } : colOverride[bp];
});
return merged;
}
return baseCol;

View File

@@ -47,18 +47,33 @@ html[data-theme="dark"] {
background: var(--imex-form-surface);
}
/* Optional: slightly tighter on phones */
/* Optional: tighter spacing on phones for better space usage */
@media (max-width: 575px) {
.ant-card-head {
padding-inline: 12px;
padding-block: 12px;
}
.ant-card-body {
padding: 12px;
}
}
/* Common form nicety */
/* Tablet optimization: slightly reduce padding */
@media (min-width: 576px) and (max-width: 991px) {
.ant-card-body {
padding: 14px;
}
}
/* Ensure form items use full column width */
.ant-col > * {
width: 100%;
}
/* Better form item spacing on mobile */
@media (max-width: 575px) {
.ant-form-item {
margin-bottom: 12px;
}
}
}

View File

@@ -1,6 +1,7 @@
import { useMutation, useQuery } from "@apollo/client/react";
import { useEffect, useState } from "react";
import { Alert, Button, Card, Checkbox, Divider, Form, Space, Switch, Table, Typography } from "antd";
import { Alert, Button, Card, Checkbox, Divider, Form, Space, Switch, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -204,7 +205,14 @@ const NotificationSettingsForm = ({ currentUser, bodyshop }) => {
<Alert title={t("notifications.labels.employee-notification")} type="warning" />
</div>
)}
<Table dataSource={dataSource} columns={columns} pagination={false} bordered rowKey="key" />
<ResponsiveTable
dataSource={dataSource}
columns={columns}
mobileColumnKeys={["email", "scenario", "app", "fcm"]}
pagination={false}
bordered
rowKey="key"
/>
<Divider />
</Card>
</Form>

View File

@@ -1,4 +1,4 @@
import { Card, Table } from "antd";
import { Card } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -11,6 +11,7 @@ import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component";
import { selectIsPartsEntry } from "../../redux/application/application.selectors";
import getPartsBasePath from "../../utils/getPartsBasePath.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -109,9 +110,10 @@ function OwnerDetailJobsComponent({ bodyshop, owner, isPartsEntry }) {
/>
}
>
<Table
<ResponsiveTable
pagination={{ placement: "bottom" }}
columns={columns}
mobileColumnKeys={["ro_number", "vehicleid", "status", "actual_completion"]}
scroll={{ x: true }}
rowKey="id"
dataSource={owner.jobs}

View File

@@ -1,6 +1,7 @@
import { Checkbox, Divider, Table } from "antd";
import { Checkbox, Divider } from "antd";
import { useTranslation } from "react-i18next";
import PhoneFormatter from "../../utils/PhoneFormatter";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function OwnerFindModalComponent({
selectedOwner,
@@ -75,9 +76,10 @@ export default function OwnerFindModalComponent({
return (
<div>
<Table
<ResponsiveTable
pagination={{ placement: "bottom" }}
columns={columns}
mobileColumnKeys={["ownr_ln", "ownr_fn", "ownr_ph1", "ownr_ph2"]}
rowKey="id"
loading={ownersListLoading}
dataSource={ownersList}

View File

@@ -1,5 +1,5 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -7,6 +7,7 @@ import { Link, useLocation, useNavigate } from "react-router-dom";
import PhoneFormatter from "../../utils/PhoneFormatter";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import { pageLimit } from "../../utils/config";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function OwnersListComponent({ loading, owners, total, refetch }) {
const search = queryString.parse(useLocation().search);
@@ -116,10 +117,11 @@ export default function OwnersListComponent({ loading, owners, total, refetch })
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(page || 1, 10), total: total }}
columns={columns}
mobileColumnKeys={["name", "ownr_ph1", "ownr_ph2"]}
rowKey="id"
scroll={{ x: true }}
dataSource={owners}

View File

@@ -1,5 +1,6 @@
import { useMutation } from "@apollo/client/react";
import { Button, Card, Col, Row, Table } from "antd";
import { Button, Card, Col, Row } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import dayjs from "../../utils/day";
import { useTranslation } from "react-i18next";
import { UPDATE_PARTS_DISPATCH_LINE } from "../../graphql/parts-dispatch.queries";
@@ -67,7 +68,12 @@ export default function PartsDispatchExpander({ dispatch }) {
<Card>
<Row gutter={[16, 16]}>
<Col span={24}>
<Table rowKey={"id"} dataSource={dispatch.parts_dispatch_lines} columns={columns} />
<ResponsiveTable
rowKey={"id"}
dataSource={dispatch.parts_dispatch_lines}
columns={columns}
mobileColumnKeys={["quantity", "joblineid", "accepted_at"]}
/>
</Col>
</Row>
</Card>

View File

@@ -1,5 +1,6 @@
import { MinusCircleTwoTone, PlusCircleTwoTone, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table } from "antd";
import { Button, Card, Input, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -106,7 +107,7 @@ export function PartDispatchTableComponent({ bodyshop, job, billsQuery }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={billsQuery.loading}
scroll={{
x: true // y: "50rem"
@@ -123,6 +124,7 @@ export function PartDispatchTableComponent({ bodyshop, job, billsQuery }) {
)
}}
columns={columns}
mobileColumnKeys={["number", "employeeid", "percent_accepted", "actions"]}
rowKey="id"
dataSource={billsQuery.data ? billsQuery.data.parts_dispatch : []}
onChange={handleTableChange}

View File

@@ -1,7 +1,8 @@
import { DeleteFilled } from "@ant-design/icons";
import { PageHeader } from "@ant-design/pro-layout";
import { useLazyQuery, useMutation } from "@apollo/client/react";
import { Button, Drawer, Grid, Popconfirm, Space, Table } from "antd";
import { Button, Drawer, Grid, Popconfirm, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import queryString from "query-string";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -368,11 +369,12 @@ export function PartsOrderListTableDrawerComponent({
}
extra={recordActions(record)}
/>
<Table
<ResponsiveTable
scroll={{
x: true //y: "50rem"
}}
columns={columns}
mobileColumnKeys={["status", "line_desc", "actions", "quantity"]}
rowKey="id"
dataSource={record.parts_order_lines}
onChange={handleTableChange}

View File

@@ -1,6 +1,6 @@
import { DeleteFilled, EyeFilled, SyncOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Button, Card, Checkbox, Input, Popconfirm, Space, Table } from "antd";
import { Button, Card, Checkbox, Input, Popconfirm, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
@@ -21,6 +21,7 @@ import PrintWrapper from "../print-wrapper/print-wrapper.component";
import PartsOrderDrawer from "./parts-order-list-table-drawer.component";
import ShareToTeamsButton from "../share-to-teams/share-to-teams.component.jsx";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
@@ -309,13 +310,14 @@ export function PartsOrderListTableComponent({
setPartsReceiveContext={setPartsReceiveContext}
setTaskUpsertContext={setTaskUpsertContext}
/>
<Table
<ResponsiveTable
loading={billsQuery.loading}
scroll={{
x: true
//y: "50rem"
}}
columns={columns}
mobileColumnKeys={["vendorname", "order_number", "order_date", "actions"]}
rowKey="id"
dataSource={filteredPartsOrders}
onChange={handleTableChange}

View File

@@ -1,4 +1,5 @@
import { Card, Table } from "antd";
import { Card } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -164,8 +165,9 @@ export function PartsQueueJobLinesComponent({ loading, jobLines }) {
return (
<Card title={t("jobs.labels.parts_lines")}>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["status", "line_desc", "line_no", "oem_partno"]}
rowKey="id"
loading={loading}
pagination={false}

View File

@@ -1,6 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
import { Button, Card, Checkbox, Input, Space } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useState } from "react";
@@ -19,6 +19,7 @@ import AlertComponent from "../alert/alert.component";
import JobRemoveFromPartsQueue from "../job-remove-from-parst-queue/job-remove-from-parts-queue.component";
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import ProductionListColumnComment from "../production-list-columns/production-list-columns.comment.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
import JobPartsReceived from "../job-parts-received/job-parts-received.component";
@@ -310,7 +311,7 @@ export function PartsQueueListComponent({ bodyshop }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{
placement: "top",
@@ -319,6 +320,7 @@ export function PartsQueueListComponent({ bodyshop }) {
// total: data && data.jobs_aggregate.aggregate.count,
}}
columns={columns}
mobileColumnKeys={["ro_number", "ownr_ln", "status", "vehicle", "partsstatus"]}
rowKey="id"
dataSource={jobs}
style={{ height: "100%" }}

View File

@@ -1,6 +1,6 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { useApolloClient } from "@apollo/client/react";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import axios from "axios";
import queryString from "query-string";
import { useEffect, useState } from "react";
@@ -19,6 +19,7 @@ import { alphaSort } from "../../utils/sorters";
import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table-modal.container";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -258,7 +259,7 @@ export function PaymentsListPaginated({
</Space>
}
>
<Table
<ResponsiveTable
loading={loading || searchLoading}
scroll={{ x: true }}
pagination={
@@ -275,6 +276,7 @@ export function PaymentsListPaginated({
}
}
columns={columns}
mobileColumnKeys={["ro_number", "owner", "date", "amount", "actions"]}
rowKey="id"
dataSource={search?.search ? openSearchResults : payments}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { useQuery } from "@apollo/client/react";
import { Input, Table, Typography } from "antd";
import { Input, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
@@ -132,8 +133,9 @@ function PhoneNumberConsentList({ bodyshop }) {
enterButton
/>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["phone_number", "created_at"]}
dataSource={optOutData?.phone_number_opt_out}
loading={optOutLoading /* || ownersLoading*/}
rowKey="id"

View File

@@ -1,4 +1,5 @@
import { Button, Card, Col, Input, Table, Typography } from "antd";
import { Button, Card, Col, Input, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -48,7 +49,14 @@ export default function ProfileShopsComponent({ loading, data, updateActiveShop
/>
}
>
<Table pagination={false} loading={loading} columns={columns} rowKey="id" dataSource={filteredData} />
<ResponsiveTable
pagination={false}
loading={loading}
columns={columns}
mobileColumnKeys={["actions", "shopname", "active"]}
rowKey="id"
dataSource={filteredData}
/>
</Card>
</Col>
);

View File

@@ -0,0 +1,52 @@
import { Grid, Table } from "antd";
import { useMemo } from "react";
function ResponsiveTable({ columns, mobileColumnKeys, scroll, ...rest }) {
const screens = Grid.useBreakpoint();
const isPhone = !screens.md;
const isResponsiveFilteringEnabled = ["1", "true", "yes", "on"].includes(
String(import.meta.env.VITE_APP_ENABLE_RESPONSIVE_TABLE_FILTERING || "")
.trim()
.toLowerCase()
);
const resolvedColumns = useMemo(() => {
if (
!isResponsiveFilteringEnabled ||
!Array.isArray(columns) ||
!isPhone ||
!Array.isArray(mobileColumnKeys) ||
mobileColumnKeys.length === 0
) {
return columns;
}
const visibleColumnKeys = new Set(mobileColumnKeys);
const filteredColumns = columns.filter((column) => {
const key = column?.key ?? column?.dataIndex;
// Keep columns with no stable key to avoid accidental loss.
if (key == null) return true;
if (Array.isArray(key)) {
return key.some((part) => visibleColumnKeys.has(part));
}
return visibleColumnKeys.has(key);
});
return filteredColumns.length > 0 ? filteredColumns : columns;
}, [columns, isPhone, isResponsiveFilteringEnabled, mobileColumnKeys]);
const resolvedScroll = scroll ?? { x: "max-content" };
return <Table columns={resolvedColumns} scroll={resolvedScroll} {...rest} />;
}
ResponsiveTable.Summary = Table.Summary;
ResponsiveTable.Column = Table.Column;
ResponsiveTable.ColumnGroup = Table.ColumnGroup;
ResponsiveTable.SELECTION_COLUMN = Table.SELECTION_COLUMN;
ResponsiveTable.EXPAND_COLUMN = Table.EXPAND_COLUMN;
export default ResponsiveTable;

View File

@@ -1,6 +1,7 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Input, Modal, Space, Table, Typography } from "antd";
import { Button, Card, Input, Modal, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -140,8 +141,9 @@ export default function ScoreboardJobsList() {
</Space>
}
>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["ro_number", "owner", "vehicle", "date", "actions"]}
rowKey="id"
dataSource={data ? data.scoreboard : []}
loading={loading}

View File

@@ -1,4 +1,5 @@
import { Card, Col, Row, Statistic, Table, Typography } from "antd";
import { Card, Col, Row, Statistic, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -98,8 +99,9 @@ export function ScoreboardTicketsStats({ data }) {
<Typography.Text type="secondary">{t("scoreboard.labels.calendarperiod")}</Typography.Text>
</Col>
<Col md={24} lg={20}>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["employee_number", "totalThisWeek", "totalLastWeek", "totalThisMonth"]}
rowKey="employee_number"
dataSource={tableData}
id="employee_number"

View File

@@ -1,7 +1,8 @@
import { DeleteFilled } from "@ant-design/icons";
import { useApolloClient, useMutation, useQuery } from "@apollo/client/react";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Card, Form, Input, InputNumber, Select, Switch, Table } from "antd";
import { Button, Card, Form, Input, InputNumber, Select, Switch } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useForm } from "antd/es/form/Form";
import queryString from "query-string";
import { useEffect } from "react";
@@ -380,9 +381,10 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
</Form.List>
</Form>
<Table
<ResponsiveTable
title={() => <ShopEmployeeAddVacation employee={data && data.employees_by_pk} />}
columns={columns}
mobileColumnKeys={["start", "length", "actions"]}
rowKey={"id"}
dataSource={data?.employees_by_pk?.employee_vacations ?? []}
/>

View File

@@ -1,9 +1,10 @@
import { Button, Table } from "antd";
import { Button } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
import { alphaSort } from "../../utils/sorters";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function ShopEmployeesListComponent({ loading, employees }) {
const { t } = useTranslation();
@@ -89,7 +90,7 @@ export default function ShopEmployeesListComponent({ loading, employees }) {
];
return (
<div>
<Table
<ResponsiveTable
title={() => {
return (
<Button
@@ -106,6 +107,7 @@ export default function ShopEmployeesListComponent({ loading, employees }) {
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["employee_number", "employee_name", "active"]}
rowKey="id"
dataSource={employees}
rowSelection={{

View File

@@ -1,7 +1,8 @@
import { Button, Table } from "antd";
import { Button } from "antd";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function ShopEmployeeTeamsListComponent({ loading, employee_teams }) {
const { t } = useTranslation();
@@ -27,7 +28,7 @@ export default function ShopEmployeeTeamsListComponent({ loading, employee_teams
return (
<div>
<Table
<ResponsiveTable
title={() => {
return (
<Button
@@ -44,6 +45,7 @@ export default function ShopEmployeeTeamsListComponent({ loading, employee_teams
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["name"]}
rowKey="id"
dataSource={employee_teams}
rowSelection={{

View File

@@ -1,5 +1,5 @@
import { useQuery } from "@apollo/client/react";
import { Button, Table } from "antd";
import { Button } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -7,6 +7,7 @@ import { QUERY_SHOP_ASSOCIATIONS } from "../../graphql/user.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import ShopUsersAuthEdit from "../shop-users-auth-edit/shop-users-auth-edit.component";
const mapStateToProps = createStructuredSelector({
@@ -66,10 +67,11 @@ export function ShopInfoUsersComponent({ bodyshop }) {
}
return (
<div>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["email", "authlevel", "actions"]}
rowKey="id"
dataSource={data && data.associations}
/>

View File

@@ -1,5 +1,5 @@
import { CarOutlined, SettingOutlined, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import axios from "axios";
import _ from "lodash";
import queryString from "query-string";
@@ -20,6 +20,7 @@ import * as Sentry from "@sentry/react";
import getPartsBasePath from "../../utils/getPartsBasePath.js";
import { toggleDarkMode } from "../../redux/application/application.actions.js";
import { FaMoon, FaSun } from "react-icons/fa";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -243,7 +244,7 @@ export function SimplifiedPartsJobsListComponent({
</Space>
}
>
<Table
<ResponsiveTable
loading={loading || searchLoading}
pagination={
search?.search
@@ -259,6 +260,7 @@ export function SimplifiedPartsJobsListComponent({
}
}
columns={columns}
mobileColumnKeys={["ro_number", "ownr_ln", "status", "vehicle", "partsstatus"]}
rowKey="id"
dataSource={search?.search ? openSearchResults : jobs}
onChange={handleTableChange}

View File

@@ -7,7 +7,7 @@ import {
PlusCircleFilled,
SyncOutlined
} from "@ant-design/icons";
import { Button, Card, Space, Switch, Table } from "antd";
import { Button, Card, Space, Switch } from "antd";
import queryString from "query-string";
import { useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
@@ -20,6 +20,7 @@ import dayjs from "../../utils/day";
import ShareToTeamsButton from "../share-to-teams/share-to-teams.component.jsx";
import PriorityLabel from "../../utils/tasksPriorityLabel.jsx";
import { logImEXEvent } from "../../firebase/firebase.utils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
/**
* Task List Component
@@ -345,7 +346,7 @@ function TaskListComponent({
return (
<Card title={titleTranslation} extra={tasksExtra()}>
<Table
<ResponsiveTable
loading={loading}
pagination={{
pageSize: pageLimit,
@@ -355,8 +356,8 @@ function TaskListComponent({
showQuickJumper: true
}}
columns={columns}
mobileColumnKeys={["title", "due_date", "priority", "toggleCompleted"]}
rowKey="id"
scroll={{ x: true }}
dataSource={tasks}
onChange={handleTableChange}
expandable={{

View File

@@ -1,6 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Input, Space, Table } from "antd";
import { Button, Card, Input, Space } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -13,6 +13,7 @@ import { onlyUnique } from "../../utils/arrayHelper";
import { alphaSort } from "../../utils/sorters";
import AlertComponent from "../alert/alert.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -170,10 +171,11 @@ export function TechLookupJobsList({ bodyshop }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={false}
columns={columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle"]}
rowKey="id"
dataSource={jobs}
scroll={{ x: true }}

View File

@@ -1,5 +1,6 @@
import { useQuery } from "@apollo/client/react";
import { Button, Form, InputNumber, Modal, Radio, Select, Space, Table, Typography } from "antd";
import { Button, Form, InputNumber, Modal, Radio, Select, Space, Typography } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -98,7 +99,18 @@ export function TimeTicketListTeamPay({ bodyshop, context }) {
<Form.Item name="percent">
<Space.Compact>
<InputNumber min={0} max={100} precision={1} />
<span style={{ padding: "0 11px", backgroundColor: "#fafafa", border: "1px solid #d9d9d9", borderLeft: 0, display: "flex", alignItems: "center" }}>%</span>
<span
style={{
padding: "0 11px",
backgroundColor: "#fafafa",
border: "1px solid #d9d9d9",
borderLeft: 0,
display: "flex",
alignItems: "center"
}}
>
%
</span>
</Space.Compact>
</Form.Item>
</LayoutFormRow>
@@ -134,7 +146,7 @@ export function TimeTicketListTeamPay({ bodyshop, context }) {
}
return (
<Table
<ResponsiveTable
dataSource={data}
rowKey={"employeeid"}
title={() => (
@@ -182,6 +194,7 @@ export function TimeTicketListTeamPay({ bodyshop, context }) {
key: "pay"
}
]}
mobileColumnKeys={["employee", "cost_center", "productivehrs", "pay"]}
/>
);
}}

View File

@@ -1,6 +1,7 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Card, Checkbox, Space, Table } from "antd";
import { Button, Card, Checkbox, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -327,9 +328,10 @@ export function TimeTicketList({
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
columns={columns}
mobileColumnKeys={["ro_number", "date", "actions", "committed_at"]}
rowKey="id"
scroll={{
x: true
@@ -340,23 +342,23 @@ export function TimeTicketList({
if (Enhanced_Payroll.treatment === "on") return null;
if (Enhanced_Payroll.treatment === "off")
return (
<Table.Summary.Row>
<Table.Summary.Cell>{t("general.labels.totals")}</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell />
<Table.Summary.Cell>{totals.productivehrs.toFixed(1)}</Table.Summary.Cell>
<Table.Summary.Cell>{totals.actualhrs.toFixed(1)}</Table.Summary.Cell>
<Table.Summary.Cell>
<ResponsiveTable.Summary.Row>
<ResponsiveTable.Summary.Cell>{t("general.labels.totals")}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell>{totals.productivehrs.toFixed(1)}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>{totals.actualhrs.toFixed(1)}</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell>
{totals.actualhrs === 0 || !totals.actualhrs
? "∞"
: `${((totals.productivehrs / totals.actualhrs) * 100).toFixed(
2
)}% ${t("timetickets.labels.efficiency")}`}
</Table.Summary.Cell>
<Table.Summary.Cell />
<Table.Summary.Cell />
<Table.Summary.Cell />
</Table.Summary.Row>
</ResponsiveTable.Summary.Cell>
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
<ResponsiveTable.Summary.Cell />
</ResponsiveTable.Summary.Row>
);
}}
locale={{

View File

@@ -1,4 +1,5 @@
import { Card, Col, Row, Table } from "antd";
import { Card, Col, Row } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import _ from "lodash";
import dayjs from "../../utils/day";
import { useMemo, useState } from "react";
@@ -213,12 +214,13 @@ const JobRelatedTicketsTable = ({ loading, jobTickets, startDate, endDate }) =>
return (
<Card title={t("timetickets.labels.jobhours")}>
<Table
<ResponsiveTable
loading={loading}
scroll={{
x: true // y: "50rem"
}}
columns={columns}
mobileColumnKeys={["total", "actions", "empname", "actHrs"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}
@@ -288,12 +290,13 @@ const ShiftRelatedTicketsTable = ({ loading, shiftTickets, startDate, endDate })
return (
<Card title={t("timetickets.labels.clockhours")}>
<Table
<ResponsiveTable
loading={loading}
scroll={{
x: true // y: "50rem"
}}
columns={columns}
mobileColumnKeys={["total", "actions", "empname", "actHrs"]}
rowKey="id"
dataSource={data}
onChange={handleTableChange}

View File

@@ -1,5 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Space, Table, Tag } from "antd";
import { Button, Card, Space, Tag } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import Dinero from "dinero.js";
import queryString from "query-string";
import { useState } from "react";
@@ -180,9 +181,10 @@ export function TtApprovalsListComponent({
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
columns={columns}
mobileColumnKeys={["ro_number", "date", "employeeid", "cost_center"]}
rowKey="id"
scroll={{
x: true

View File

@@ -1,4 +1,4 @@
import { Card, Table } from "antd";
import { Card } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -12,6 +12,7 @@ import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-displa
import VehicleDetailUpdateJobsComponent from "../vehicle-detail-update-jobs/vehicle-detail-update-jobs.component";
import { selectIsPartsEntry } from "../../redux/application/application.selectors";
import getPartsBasePath from "../../utils/getPartsBasePath.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -107,8 +108,9 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop, isPartsEntry })
/>
}
>
<Table
<ResponsiveTable
columns={columns}
mobileColumnKeys={["ro_number", "owner", "status", "actual_completion"]}
rowKey="id"
scroll={{ x: true }}
dataSource={vehicle.jobs}

View File

@@ -1,5 +1,5 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -7,6 +7,7 @@ import { Link, useLocation, useNavigate } from "react-router-dom";
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
import { pageLimit } from "../../utils/config";
import { alphaSort } from "../../utils/sorters";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function VehiclesListComponent({ loading, vehicles, total, refetch, basePath = "/manage" }) {
const search = queryString.parse(useLocation().search);
@@ -103,10 +104,11 @@ export default function VehiclesListComponent({ loading, vehicles, total, refetc
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top", pageSize: pageLimit, current: parseInt(page || 1), total: total }}
columns={columns}
mobileColumnKeys={["v_vin", "description", "plate_no"]}
rowKey="id"
scroll={{ x: true }}
dataSource={vehicles}

View File

@@ -1,10 +1,11 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Tag } from "antd";
import { Button, Card, Input, Space, Tag } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom";
import { alphaSort } from "../../utils/sorters";
import ResponsiveTable from "../responsive-table/responsive-table.component";
export default function VendorsListComponent({ handleNewVendor, loading, handleOnRowClick, vendors, refetch }) {
const search = queryString.parse(useLocation().search);
@@ -85,10 +86,11 @@ export default function VendorsListComponent({ handleNewVendor, loading, handleO
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{ placement: "top" }}
columns={columns}
mobileColumnKeys={["name", "phone", "city"]}
rowKey="id"
onChange={handleTableChange}
dataSource={filteredVendors}

View File

@@ -1,5 +1,5 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import { Button, Card, Checkbox, Input, Space, Typography } from "antd";
import { useQuery } from "@apollo/client/react";
import axios from "axios";
import queryString from "query-string";
@@ -18,6 +18,7 @@ import { pageLimit } from "../../utils/config";
import { alphaSort, dateSort } from "../../utils/sorters";
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
import { logImEXEvent } from "../../firebase/firebase.utils";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
const mapDispatchToProps = (dispatch) => ({
setBillEnterContext: (context) => dispatch(setModalContext({ context: context, modal: "billEnter" }))
@@ -229,7 +230,7 @@ export function BillsListPage({ loading, data, refetch, total, setBillEnterConte
>
<PartsOrderModalContainer />
<Table
<ResponsiveTable
loading={loading || searchLoading}
// scroll={{
// x: "50%", // y: "40rem"
@@ -249,6 +250,7 @@ export function BillsListPage({ loading, data, refetch, total, setBillEnterConte
}
}
columns={columns}
mobileColumnKeys={["vendorname", "invoice_number", "ro_number", "total", "actions"]}
rowKey="id"
dataSource={search?.search ? openSearchResults : data}
onChange={handleTableChange}

View File

@@ -1,6 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import { Button, Card, Checkbox, Input, Space, Typography } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
@@ -8,6 +8,7 @@ import { connect } from "react-redux";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import AlertComponent from "../../components/alert/alert.component";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
import { QUERY_EXPORT_LOG_PAGINATED } from "../../graphql/accounting.queries";
import { DateTimeFormatter } from "../../utils/DateFormatter";
import { pageLimit } from "../../utils/config";
@@ -186,7 +187,7 @@ export function ExportLogsPageComponent() {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{
placement: "top",
@@ -195,6 +196,7 @@ export function ExportLogsPageComponent() {
total: data && data.search_exportlog_aggregate.aggregate.count
}}
columns={columns}
mobileColumnKeys={["created_at", "ro_number", "successful", "message"]}
rowKey="id"
dataSource={data?.search_exportlog}
style={{ height: "100%" }}

View File

@@ -1,6 +1,6 @@
import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import { Button, Card, Input, Space, Typography } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
@@ -8,6 +8,7 @@ import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import AlertComponent from "../../components/alert/alert.component";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
import { QUERY_PHONEBOOK_PAGINATED } from "../../graphql/phonebook.queries";
import { selectAuthLevel, selectBodyshop } from "../../redux/user/user.selectors";
import ChatOpenButton from "../../components/chat-open-button/chat-open-button.component";
@@ -172,7 +173,7 @@ export function PhonebookPageComponent({ bodyshop, authLevel }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{
placement: "top",
@@ -181,6 +182,7 @@ export function PhonebookPageComponent({ bodyshop, authLevel }) {
total: data && data.search_phonebook_aggregate.aggregate.count
}}
columns={columns}
mobileColumnKeys={["firstname", "lastname", "company", "phone1", "phone2"]}
rowKey="id"
dataSource={data?.search_phonebook}
//scroll={{ x: true }}

View File

@@ -1,6 +1,7 @@
import { useQuery } from "@apollo/client/react";
import { useState } from "react";
import { Button, Card, Input, Space, Table } from "antd";
import { Button, Card, Input, Space } from "antd";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_JOBS_TECH_ASIGNED_TO_BY_TEAM } from "../../graphql/jobs.queries";
@@ -188,10 +189,11 @@ export function TechAssignedProdJobs({ setTimeTicketTaskContext, technician, bod
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={false}
columns={columns}
mobileColumnKeys={["ro_number", "owner", "status", "vehicle", "plate_no"]}
rowKey="id"
dataSource={jobs}
scroll={{ x: true }}

View File

@@ -1,6 +1,7 @@
import { MinusCircleTwoTone, PlusCircleTwoTone, SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Space, Table } from "antd";
import { Button, Card, Space } from "antd";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -108,7 +109,7 @@ export function TechDispatchedParts({ technician, bodyshop }) {
</Space>
}
>
<Table
<ResponsiveTable
loading={loading}
pagination={{
pageSize: 25,
@@ -117,6 +118,7 @@ export function TechDispatchedParts({ technician, bodyshop }) {
showSizeChanger: false
}}
columns={columns}
mobileColumnKeys={["ro_number", "status", "vehicle", "actions"]}
rowKey="id"
dataSource={parts_dispatch}
scroll={{ x: true }}