IO-2604 Add vendor tags to search select & vendor edit screen.

This commit is contained in:
Patrick Fic
2025-07-22 10:03:07 -07:00
parent 953e70efef
commit c45f38e47b
12 changed files with 12983 additions and 11754 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -52,6 +52,7 @@ const VendorSearchSelect = ({ value, onChange, options, onSelect, disabled, pref
> >
{label} {label}
</div> </div>
{discount && discount !== 0 ? <Tag color="green">{`${discount * 100}%`}</Tag> : null} {discount && discount !== 0 ? <Tag color="green">{`${discount * 100}%`}</Tag> : null}
</div> </div>
); );
@@ -116,6 +117,11 @@ const VendorSearchSelect = ({ value, onChange, options, onSelect, disabled, pref
{o.name} {o.name}
</div> </div>
<Space style={{ marginLeft: "1rem" }}> <Space style={{ marginLeft: "1rem" }}>
{o.tags?.map((tag, idx) => (
<Tag key={idx} style={{ marginLeft: "0.5rem" }}>
{tag}
</Tag>
))}
{o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>} {o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>}
{o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null} {o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null}
</Space> </Space>

View File

@@ -1,7 +1,7 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { useApolloClient } from "@apollo/client"; import { useApolloClient } from "@apollo/client";
import { useSplitTreatments } from "@splitsoftware/splitio-react"; import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { Button, Divider, Form, Input, InputNumber, Space, Switch } from "antd"; import { Button, Divider, Form, Input, InputNumber, Select, Space, Switch } from "antd";
import { PageHeader } from "@ant-design/pro-layout"; import { PageHeader } from "@ant-design/pro-layout";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -179,6 +179,18 @@ export function VendorsFormComponent({
} }
</LayoutFormRow> </LayoutFormRow>
<Form.Item
name="tags"
label={t("vendor.fields.tags")}
rules={[
{
//message: t("general.validation.required"),
type: "array"
}
]}
>
<Select mode="tags" />
</Form.Item>
{DmsAp.treatment === "on" && ( {DmsAp.treatment === "on" && (
<Form.Item label={t("vendors.fields.dmsid")} name="dmsid"> <Form.Item label={t("vendors.fields.dmsid")} name="dmsid">
<Input /> <Input />

View File

@@ -1,5 +1,5 @@
import { SyncOutlined } from "@ant-design/icons"; import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table } from "antd"; import { Button, Card, Input, Space, Table, Tag } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -38,6 +38,18 @@ export default function VendorsListComponent({ handleNewVendor, loading, handleO
title: t("vendors.fields.city"), title: t("vendors.fields.city"),
dataIndex: "city", dataIndex: "city",
key: "city" key: "city"
},
{
title: t("vendors.fields.tags"),
dataIndex: "tags",
key: "tags",
render: (text, record) => (
<Space>
{record?.tags?.map((tag, idx) => (
<Tag key={idx}>{tag}</Tag>
))}
</Space>
)
} }
]; ];

View File

@@ -19,6 +19,7 @@ export const QUERY_VENDOR_BY_ID = gql`
active active
phone phone
dmsid dmsid
tags
} }
} }
`; `;
@@ -54,6 +55,7 @@ export const QUERY_ALL_VENDORS = gql`
city city
phone phone
active active
tags
} }
} }
`; `;
@@ -89,6 +91,7 @@ export const QUERY_ALL_VENDORS_FOR_ORDER = gql`
email email
active active
phone phone
tags
} }
jobs(where: { id: { _eq: $jobId } }) { jobs(where: { id: { _eq: $jobId } }) {
v_make_desc v_make_desc
@@ -105,6 +108,7 @@ export const SEARCH_VENDOR_AUTOCOMPLETE = gql`
cost_center cost_center
active active
favorite favorite
tags
} }
} }
`; `;
@@ -124,6 +128,7 @@ export const SEARCH_VENDOR_AUTOCOMPLETE_WITH_ADDR = gql`
email email
state state
active active
tags
} }
} }
`; `;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -48,24 +48,24 @@ export default async function RenderTemplate(
...(renderAsHtml ...(renderAsHtml
? {} ? {}
: { : {
recipe: "chrome-pdf", recipe: "chrome-pdf",
...(!ignoreCustomMargins && { ...(!ignoreCustomMargins && {
chrome: { chrome: {
marginTop: marginTop:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.headerMargin && bodyshop.logo_img_path.headerMargin &&
bodyshop.logo_img_path.headerMargin > 36 bodyshop.logo_img_path.headerMargin > 36
? bodyshop.logo_img_path.headerMargin ? bodyshop.logo_img_path.headerMargin
: "36px", : "36px",
marginBottom: marginBottom:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.footerMargin && bodyshop.logo_img_path.footerMargin &&
bodyshop.logo_img_path.footerMargin > 50 bodyshop.logo_img_path.footerMargin > 50
? bodyshop.logo_img_path.footerMargin ? bodyshop.logo_img_path.footerMargin
: "50px" : "50px"
} }
}) })
}), }),
...(renderAsExcel ? { recipe: "html-to-xlsx" } : {}), ...(renderAsExcel ? { recipe: "html-to-xlsx" } : {}),
...(renderAsText ? { recipe: "text" } : {}) ...(renderAsText ? { recipe: "text" } : {})
}, },
@@ -100,14 +100,14 @@ export default async function RenderTemplate(
chrome: { chrome: {
marginTop: marginTop:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.headerMargin && bodyshop.logo_img_path.headerMargin &&
bodyshop.logo_img_path.headerMargin > 36 bodyshop.logo_img_path.headerMargin > 36
? bodyshop.logo_img_path.headerMargin ? bodyshop.logo_img_path.headerMargin
: "36px", : "36px",
marginBottom: marginBottom:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.footerMargin && bodyshop.logo_img_path.footerMargin &&
bodyshop.logo_img_path.footerMargin > 50 bodyshop.logo_img_path.footerMargin > 50
? bodyshop.logo_img_path.footerMargin ? bodyshop.logo_img_path.footerMargin
: "50px" : "50px"
} }
@@ -182,22 +182,22 @@ export async function RenderTemplates(templateObjects, bodyshop, renderAsHtml =
...(renderAsHtml ...(renderAsHtml
? {} ? {}
: { : {
recipe: "chrome-pdf", recipe: "chrome-pdf",
chrome: { chrome: {
marginTop: marginTop:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.headerMargin && bodyshop.logo_img_path.headerMargin &&
bodyshop.logo_img_path.headerMargin > 36 bodyshop.logo_img_path.headerMargin > 36
? bodyshop.logo_img_path.headerMargin ? bodyshop.logo_img_path.headerMargin
: "36px", : "36px",
marginBottom: marginBottom:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.footerMargin && bodyshop.logo_img_path.footerMargin &&
bodyshop.logo_img_path.footerMargin > 50 bodyshop.logo_img_path.footerMargin > 50
? bodyshop.logo_img_path.footerMargin ? bodyshop.logo_img_path.footerMargin
: "50px" : "50px"
} }
}), }),
pdfOperations: [ pdfOperations: [
{ {
template: { template: {
@@ -213,14 +213,14 @@ export async function RenderTemplates(templateObjects, bodyshop, renderAsHtml =
chrome: { chrome: {
marginTop: marginTop:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.headerMargin && bodyshop.logo_img_path.headerMargin &&
bodyshop.logo_img_path.headerMargin > 36 bodyshop.logo_img_path.headerMargin > 36
? bodyshop.logo_img_path.headerMargin ? bodyshop.logo_img_path.headerMargin
: "36px", : "36px",
marginBottom: marginBottom:
bodyshop.logo_img_path && bodyshop.logo_img_path &&
bodyshop.logo_img_path.footerMargin && bodyshop.logo_img_path.footerMargin &&
bodyshop.logo_img_path.footerMargin > 50 bodyshop.logo_img_path.footerMargin > 50
? bodyshop.logo_img_path.footerMargin ? bodyshop.logo_img_path.footerMargin
: "50px" : "50px"
}, },
@@ -302,7 +302,6 @@ export const fetchFilterData = async ({ name }) => {
const jsReportFilters = await cleanAxios.get(`${server}/odata/assets?$filter=name eq '${name}.filters'`, { const jsReportFilters = await cleanAxios.get(`${server}/odata/assets?$filter=name eq '${name}.filters'`, {
headers: { Authorization: jsrAuth } headers: { Authorization: jsrAuth }
}); });
console.log("🚀 ~ fetchFilterData ~ jsReportFilters:", jsReportFilters);
let parsedFilterData; let parsedFilterData;
let useShopSpecificTemplate = false; let useShopSpecificTemplate = false;

View File

@@ -4909,6 +4909,7 @@
- critical - critical
- id - id
- jobid - jobid
- pinned
- private - private
- text - text
- type - type
@@ -4923,6 +4924,7 @@
- critical - critical
- id - id
- jobid - jobid
- pinned
- private - private
- text - text
- type - type
@@ -4947,6 +4949,7 @@
- critical - critical
- id - id
- jobid - jobid
- pinned
- private - private
- text - text
- type - type
@@ -7120,6 +7123,7 @@
- state - state
- street1 - street1
- street2 - street2
- tags
- updated_at - updated_at
- zip - zip
select_permissions: select_permissions:
@@ -7143,6 +7147,7 @@
- state - state
- street1 - street1
- street2 - street2
- tags
- updated_at - updated_at
- zip - zip
filter: filter:
@@ -7176,6 +7181,7 @@
- state - state
- street1 - street1
- street2 - street2
- tags
- updated_at - updated_at
- zip - zip
filter: filter:

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."vendors" add column "tags" jsonb
-- not null default jsonb_build_array();

View File

@@ -0,0 +1,2 @@
alter table "public"."vendors" add column "tags" jsonb
not null default jsonb_build_array();