Merged in feature/IO-3637-DMS-ID-Production-Board-Column (pull request #3176)

Feature/IO-3637 DMS ID Production Board Column
This commit is contained in:
Allan Carr
2026-04-02 23:07:28 +00:00
11 changed files with 92 additions and 45 deletions

View File

@@ -58,6 +58,7 @@ export function ProductionColumnsComponent({
const columnKeys = columns.map((i) => i.key); const columnKeys = columns.map((i) => i.key);
const cols = dataSource({ const cols = dataSource({
bodyshop,
technician, technician,
data, data,
state: tableState, state: tableState,

View File

@@ -609,7 +609,19 @@ const productionListColumnsData = ({ technician, state, activeStatuses, data, bo
ellipsis: true, ellipsis: true,
render: (text, record) => <TimeFormatter>{record.date_repairstarted}</TimeFormatter> render: (text, record) => <TimeFormatter>{record.date_repairstarted}</TimeFormatter>
} },
...(bodyshop && bodyshop.rr_dealerid
? [
{
title: i18n.t("jobs.fields.dms.id"),
dataIndex: "dms_id",
key: "dms_id",
ellipsis: true,
sorter: (a, b) => alphaSort(a.dms_id, b.dms_id),
sortOrder: state.sortedInfo.columnKey === "dms_id" && state.sortedInfo.order
}
]
: []),
]; ];
}; };
export default productionListColumnsData; export default productionListColumnsData;

View File

@@ -244,6 +244,7 @@ export function ProductionListConfigManager({
nextConfig.columns.columnKeys.map((k) => { nextConfig.columns.columnKeys.map((k) => {
return { return {
...ProductionListColumns({ ...ProductionListColumns({
bodyshop,
technician, technician,
state: ensureDefaultState(state), state: ensureDefaultState(state),
refetch, refetch,
@@ -270,6 +271,7 @@ export function ProductionListConfigManager({
activeConfig.columns.columnKeys.map((k) => { activeConfig.columns.columnKeys.map((k) => {
return { return {
...ProductionListColumns({ ...ProductionListColumns({
bodyshop,
technician, technician,
state: ensureDefaultState(state), state: ensureDefaultState(state),
refetch, refetch,

View File

@@ -197,6 +197,7 @@ export const QUERY_EXACT_JOB_IN_PRODUCTION = gql`
employee_prep employee_prep
employee_csr employee_csr
date_repairstarted date_repairstarted
dms_id
joblines_status { joblines_status {
part_type part_type
status status
@@ -269,6 +270,7 @@ export const QUERY_EXACT_JOBS_IN_PRODUCTION = gql`
employee_prep employee_prep
employee_csr employee_csr
date_repairstarted date_repairstarted
dms_id
joblines_status { joblines_status {
part_type part_type
status status
@@ -2671,6 +2673,7 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
suspended suspended
job_totals job_totals
date_repairstarted date_repairstarted
dms_id
joblines_status { joblines_status {
part_type part_type
status status

View File

@@ -1,20 +1,17 @@
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager"); const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
const { defaultProvider } = require("@aws-sdk/credential-provider-node"); const { defaultProvider } = require("@aws-sdk/credential-provider-node");
const { isString, isEmpty } = require("lodash"); const { InstanceRegion, InstanceIsLocalStackEnabled, InstanceLocalStackEndpoint } = require("../utils/instanceMgr");
const CHATTER_BASE_URL = process.env.CHATTER_API_BASE_URL || "https://api.chatterresearch.com"; const CHATTER_BASE_URL = process.env.CHATTER_API_BASE_URL || "https://api.chatterresearch.com";
const AWS_REGION = process.env.AWS_REGION || "ca-central-1";
// Configure SecretsManager client with localstack support // Configure SecretsManager client with localstack support
const secretsClientOptions = { const secretsClientOptions = {
region: AWS_REGION, region: InstanceRegion(),
credentials: defaultProvider() credentials: defaultProvider()
}; };
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME); if (InstanceIsLocalStackEnabled()) {
secretsClientOptions.endpoint = InstanceLocalStackEndpoint();
if (isLocal) {
secretsClientOptions.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`;
} }
const secretsClient = new SecretsManagerClient(secretsClientOptions); const secretsClient = new SecretsManagerClient(secretsClientOptions);

View File

@@ -3,7 +3,7 @@ const Dinero = require("dinero.js");
const moment = require("moment-timezone"); const moment = require("moment-timezone");
const logger = require("../utils/logger"); const logger = require("../utils/logger");
const InstanceManager = require("../utils/instanceMgr").default; const InstanceManager = require("../utils/instanceMgr").default;
const { isString, isEmpty } = require("lodash"); const { InstanceIsLocalStackEnabled } = require("../utils/instanceMgr");
const fs = require("fs"); const fs = require("fs");
const client = require("../graphql-client/graphql-client").client; const client = require("../graphql-client/graphql-client").client;
const { sendServerEmail, sendMexicoBillingEmail } = require("../email/sendemail"); const { sendServerEmail, sendMexicoBillingEmail } = require("../email/sendemail");
@@ -35,10 +35,9 @@ const S3_BUCKET_NAME = InstanceManager({
rome: "rome-carfax-uploads" rome: "rome-carfax-uploads"
}); });
const region = InstanceManager.InstanceRegion; const region = InstanceManager.InstanceRegion;
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME);
const uploadToS3 = (jsonObj, bucketName = S3_BUCKET_NAME) => { const uploadToS3 = (jsonObj, bucketName = S3_BUCKET_NAME) => {
const webPath = isLocal const webPath = InstanceIsLocalStackEnabled()
? `https://${bucketName}.s3.localhost.localstack.cloud:4566/${jsonObj.filename}` ? `https://${bucketName}.s3.localhost.localstack.cloud:4566/${jsonObj.filename}`
: `https://${bucketName}.s3.${region}.amazonaws.com/${jsonObj.filename}`; : `https://${bucketName}.s3.${region}.amazonaws.com/${jsonObj.filename}`;

View File

@@ -5,7 +5,8 @@ const logger = require("../utils/logger");
const fs = require("fs"); const fs = require("fs");
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager"); const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
const { defaultProvider } = require("@aws-sdk/credential-provider-node"); const { defaultProvider } = require("@aws-sdk/credential-provider-node");
const { isString, isEmpty } = require("lodash"); const { InstanceIsLocalStackEnabled, InstanceLocalStackEndpoint } = require("../utils/instanceMgr");
let Client = require("ssh2-sftp-client"); let Client = require("ssh2-sftp-client");
const client = require("../graphql-client/graphql-client").client; const client = require("../graphql-client/graphql-client").client;
@@ -151,10 +152,8 @@ async function getPrivateKey() {
credentials: defaultProvider() credentials: defaultProvider()
}; };
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME); if (InstanceIsLocalStackEnabled()) {
secretsClientOptions.endpoint = InstanceLocalStackEndpoint();
if (isLocal) {
secretsClientOptions.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`;
} }
const client = new SecretsManagerClient(secretsClientOptions); const client = new SecretsManagerClient(secretsClientOptions);

View File

@@ -1,20 +1,17 @@
const { isString, isEmpty } = require("lodash");
const { defaultProvider } = require("@aws-sdk/credential-provider-node"); const { defaultProvider } = require("@aws-sdk/credential-provider-node");
const { InstanceRegion } = require("../utils/instanceMgr"); const { InstanceRegion, InstanceIsLocalStackEnabled, InstanceLocalStackEndpoint } = require("../utils/instanceMgr");
const aws = require("@aws-sdk/client-ses"); const aws = require("@aws-sdk/client-ses");
const nodemailer = require("nodemailer"); const nodemailer = require("nodemailer");
const logger = require("../utils/logger"); const logger = require("../utils/logger");
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME);
const sesConfig = { const sesConfig = {
apiVersion: "latest", apiVersion: "latest",
credentials: defaultProvider(), credentials: defaultProvider(),
region: InstanceRegion() region: InstanceRegion()
}; };
if (isLocal) { if (InstanceIsLocalStackEnabled()) {
sesConfig.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`; sesConfig.endpoint = InstanceLocalStackEndpoint();
logger.logger.debug(`SES Mailer set to LocalStack end point: ${sesConfig.endpoint}`); logger.logger.debug(`SES Mailer set to LocalStack end point: ${sesConfig.endpoint}`);
} }

View File

@@ -7,14 +7,24 @@
* @property { string | object | function } promanager Return this prop if Rome. * @property { string | object | function } promanager Return this prop if Rome.
* @property { string | object | function } imex Return this prop if Rome. * @property { string | object | function } imex Return this prop if Rome.
*/ */
const { isString, isEmpty } = require("lodash");
function InstanceManager({ args, instance, debug, executeFunction, rome, promanager, imex }) { /**
* InstanceManager is a utility function that determines which property to return based on the current instance type.
* @param param0
* @param param0.args
* @param param0.instance
* @param param0.debug
* @param param0.executeFunction
* @param param0.rome
* @param param0.promanager
* @param param0.imex
* @returns {*|null}
* @constructor
*/
const InstanceManager = ({ args, instance, debug, executeFunction, rome, promanager, imex }) => {
let propToReturn = null; let propToReturn = null;
//TODO: Remove after debugging.
if (promanager) {
console.trace("ProManager Prop was used");
}
switch (instance || process.env.INSTANCE) { switch (instance || process.env.INSTANCE) {
case "IMEX": case "IMEX":
propToReturn = imex; propToReturn = imex;
@@ -50,15 +60,42 @@ function InstanceManager({ args, instance, debug, executeFunction, rome, promana
} }
if (executeFunction && typeof propToReturn === "function") return propToReturn(...args); if (executeFunction && typeof propToReturn === "function") return propToReturn(...args);
return propToReturn === undefined ? null : propToReturn; return propToReturn === undefined ? null : propToReturn;
} };
exports.InstanceRegion = () => /**
* Returns the AWS region to be used for the current instance, which is determined by the INSTANCE environment variable.
* @returns {*}
* @constructor
*/
const InstanceRegion = () =>
InstanceManager({ InstanceManager({
imex: "ca-central-1", imex: "ca-central-1",
rome: "us-east-2" rome: "us-east-2"
}); });
exports.InstanceEndpoints = () => /**
* Checks if the instance is configured to use LocalStack by verifying the presence of the LOCALSTACK_HOSTNAME
* environment variable.
* @returns {boolean}
* @constructor
*/
const InstanceIsLocalStackEnabled = () =>
isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME);
/**
* Returns the LocalStack endpoint URL based on the LOCALSTACK_HOSTNAME environment variable.
* @returns {`http://${*}:4566`}
* @constructor
*/
const InstanceLocalStackEndpoint = () => `http://${process.env.LOCALSTACK_HOSTNAME}:4566`;
/**
* Returns the appropriate endpoints for the current instance, which can be used for making API calls or other network
* requests.
* @returns {*|null}
* @constructor
*/
const InstanceEndpoints = () =>
InstanceManager({ InstanceManager({
imex: imex:
process.env?.NODE_ENV === "development" process.env?.NODE_ENV === "development"
@@ -74,4 +111,11 @@ exports.InstanceEndpoints = () =>
: "https://romeonline.io" : "https://romeonline.io"
}); });
exports.default = InstanceManager; module.exports = {
InstanceManager,
InstanceRegion,
InstanceIsLocalStackEnabled,
InstanceLocalStackEndpoint,
InstanceEndpoints,
default: InstanceManager
};

View File

@@ -2,10 +2,9 @@
const InstanceManager = require("../utils/instanceMgr").default; const InstanceManager = require("../utils/instanceMgr").default;
const winston = require("winston"); const winston = require("winston");
const WinstonCloudWatch = require("winston-cloudwatch"); const WinstonCloudWatch = require("winston-cloudwatch");
const { isString, isEmpty } = require("lodash");
const { uploadFileToS3 } = require("./s3"); const { uploadFileToS3 } = require("./s3");
const { v4 } = require("uuid"); const { v4 } = require("uuid");
const { InstanceRegion } = require("./instanceMgr"); const { InstanceRegion, InstanceIsLocalStackEnabled, InstanceLocalStackEndpoint } = require("./instanceMgr");
const getHostNameOrIP = require("./getHostNameOrIP"); const getHostNameOrIP = require("./getHostNameOrIP");
const client = require("../graphql-client/graphql-client").client; const client = require("../graphql-client/graphql-client").client;
const queries = require("../graphql-client/queries"); const queries = require("../graphql-client/queries");
@@ -48,7 +47,7 @@ const normalizeLevel = (level) => (level ? level.toLowerCase() : LOG_LEVELS.debu
const createLogger = () => { const createLogger = () => {
try { try {
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME); const isLocal = InstanceIsLocalStackEnabled();
const logGroupName = isLocal ? "development" : process.env.CLOUDWATCH_LOG_GROUP; const logGroupName = isLocal ? "development" : process.env.CLOUDWATCH_LOG_GROUP;
const winstonCloudwatchTransportDefaults = { const winstonCloudwatchTransportDefaults = {
@@ -60,7 +59,7 @@ const createLogger = () => {
}; };
if (isLocal) { if (isLocal) {
winstonCloudwatchTransportDefaults.awsOptions.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`; winstonCloudwatchTransportDefaults.awsOptions.endpoint = InstanceLocalStackEndpoint();
} }
const levelFilter = (levels) => { const levelFilter = (levels) => {

View File

@@ -7,8 +7,7 @@ const {
CopyObjectCommand CopyObjectCommand
} = require("@aws-sdk/client-s3"); } = require("@aws-sdk/client-s3");
const { defaultProvider } = require("@aws-sdk/credential-provider-node"); const { defaultProvider } = require("@aws-sdk/credential-provider-node");
const { InstanceRegion } = require("./instanceMgr"); const { InstanceRegion, InstanceIsLocalStackEnabled, InstanceLocalStackEndpoint } = require("./instanceMgr");
const { isString, isEmpty } = require("lodash");
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner"); const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
const createS3Client = () => { const createS3Client = () => {
@@ -17,10 +16,8 @@ const createS3Client = () => {
credentials: defaultProvider() credentials: defaultProvider()
}; };
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME); if (InstanceIsLocalStackEnabled()) {
S3Options.endpoint = InstanceLocalStackEndpoint();
if (isLocal) {
S3Options.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`;
S3Options.forcePathStyle = true; // Needed for LocalStack to avoid bucket name as hostname S3Options.forcePathStyle = true; // Needed for LocalStack to avoid bucket name as hostname
} }
@@ -105,7 +102,7 @@ const createS3Client = () => {
}); });
const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 360 }); const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 360 });
return presignedUrl; return presignedUrl;
} };
return { return {
uploadFileToS3, uploadFileToS3,
@@ -119,7 +116,4 @@ const createS3Client = () => {
}; };
}; };
module.exports = createS3Client(); module.exports = createS3Client();