Skip to content

Commit

Permalink
Finalizes support for the TME api
Browse files Browse the repository at this point in the history
  • Loading branch information
replaysMike committed Apr 8, 2024
1 parent d17d43f commit c2a2b49
Show file tree
Hide file tree
Showing 42 changed files with 2,370 additions and 1,071 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ export default function PartsGrid2Memoized(props) {
return 220;
case "arrowPartNumber":
return 220;
case "tmePartNumber":
return 220;
case "actions":
return 150;
default:
Expand Down Expand Up @@ -493,7 +495,7 @@ PartsGrid2Memoized.propTypes = {

PartsGrid2Memoized.defaultProps = {
loading: true,
columns: "partNumber,partId,quantity,lowStockThreshold,manufacturerPartNumber,description,partType,packageType,mountingType,location,binNumber,binNumber2,cost,digikeyPartNumber,mouserPartNumber,arrowPartNumber,datasheetUrl,print,delete,symbolName,footprintName,extensionValue1,extensionValue2",
columns: "partNumber,partId,quantity,lowStockThreshold,manufacturerPartNumber,description,partType,packageType,mountingType,location,binNumber,binNumber2,cost,digikeyPartNumber,mouserPartNumber,arrowPartNumber,tmePartNumber,datasheetUrl,print,delete,symbolName,footprintName,extensionValue1,extensionValue2",
defaultVisibleColumns: "partNumber,quantity,manufacturerPartNumber,description,partType,location,binNumber,binNumber2,cost,datasheetUrl,print,delete",
page: 1,
totalPages: 1,
Expand Down
72 changes: 70 additions & 2 deletions Binner/Binner.Web/ClientApp/src/pages/Inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export function Inventory(props) {
digiKeyPartNumber: "",
mouserPartNumber: "",
arrowPartNumber: "",
tmePartNumber: "",
location: (!pageHasParameters && viewPreferences.rememberLast && viewPreferences.lastLocation) || "",
binNumber: (!pageHasParameters && viewPreferences.rememberLast && viewPreferences.lastBinNumber) || "",
binNumber2: (!pageHasParameters && viewPreferences.rememberLast && viewPreferences.lastBinNumber2) || "",
Expand Down Expand Up @@ -293,7 +294,16 @@ export function Inventory(props) {
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}

// also map tme
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "TME" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.tmePartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}
if (mappedPart.supplier === "Mouser") {
entity.mouserPartNumber = mappedPart.supplierPartNumber || "";
Expand All @@ -317,6 +327,16 @@ export function Inventory(props) {
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map tme
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "TME" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.tmePartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}
if (mappedPart.supplier === "Arrow") {
entity.arrowPartNumber = mappedPart.supplierPartNumber || "";
Expand All @@ -340,6 +360,49 @@ export function Inventory(props) {
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map tme
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "TME" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.tmePartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}
if (mappedPart.supplier === "TME") {
entity.tmePartNumber = mappedPart.supplierPartNumber || "";
// also map digikey
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "DigiKey" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.digiKeyPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map mouser
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Mouser" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.mouserPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map arrow
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Arrow" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.arrowPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}

const lowestCostPart = _.first(
Expand Down Expand Up @@ -398,7 +461,7 @@ export function Inventory(props) {
Inventory.infoAbortController.abort();
Inventory.infoAbortController = new AbortController();
try {
const response = await fetchApi(`api/part/info?partNumber=${encodeURIComponent(partNumber.trim())}&supplierPartNumbers=digikey:${part.digiKeyPartNumber || ""},mouser:${part.mouserPartNumber || ""},arrow:${part.arrowPartNumber}`, {
const response = await fetchApi(`api/part/info?partNumber=${encodeURIComponent(partNumber.trim())}&supplierPartNumbers=digikey:${part.digiKeyPartNumber || ""},mouser:${part.mouserPartNumber || ""},arrow:${part.arrowPartNumber},tme:${part.tmePartNumber}`, {
signal: Inventory.infoAbortController.signal
});

Expand Down Expand Up @@ -763,6 +826,7 @@ export function Inventory(props) {
digiKeyPartNumber: "",
mouserPartNumber: "",
arrowPartNumber: "",
tmePartNumber: "",
location: (clearAll || !viewPreferences.rememberLast) ? "" : viewPreferences.lastLocation + "",
binNumber: (clearAll || !viewPreferences.rememberLast) ? "" : viewPreferences.lastBinNumber + "",
binNumber2: (clearAll || !viewPreferences.rememberLast) ? "" : viewPreferences.lastBinNumber2 + "",
Expand Down Expand Up @@ -1423,6 +1487,10 @@ export function Inventory(props) {
<label>{t('label.arrowPartNumber', "Arrow Part Number")}</label>
<ClearableInput placeholder='595-LM358AP' value={part.arrowPartNumber || ''} onChange={handleChange} name='arrowPartNumber' />
</Form.Field>
<Form.Field width={4}>
<label>{t('label.tmePartNumber', "TME Part Number")}</label>
<ClearableInput placeholder='LM358PWR' value={part.tmePartNumber || ''} onChange={handleChange} name='tmePartNumber' />
</Form.Field>
</Form.Group>
<Form.Group>
<Form.Field width={4}>
Expand Down
2 changes: 1 addition & 1 deletion Binner/Binner.Web/ClientApp/src/pages/LowInventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function LowInventory (props) {
const renderPartsTable = useMemo(() => {
return (<PartsGrid2Memoized
parts={parts}
columns="partNumber,lowStockThreshold,quantity,manufacturerPartNumber,description,partType,packageType,mountingType,location,binNumber,binNumber2,cost,digikeyPartNumber,mouserPartNumber,arrowPartNumber,datasheetUrl,print,delete"
columns="partNumber,lowStockThreshold,quantity,manufacturerPartNumber,description,partType,packageType,mountingType,location,binNumber,binNumber2,cost,digikeyPartNumber,mouserPartNumber,arrowPartNumber,tmePartNumber,datasheetUrl,print,delete"
defaultVisibleColumns='partNumber,lowStockThreshold,quantity,manufacturerPartNumber,description,location,binNumber,binNumber2,cost,digikeyPartNumber,mouserPartNumber,datasheetUrl,print,delete'
page={page}
totalPages={totalPages}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ export function LabelEditor(props) {
<DraggableBox name="digikeyPartNumber">{getChildrenByName('digikeyPartNumber')}</DraggableBox>
<DraggableBox name="mouserPartNumber">{getChildrenByName('mouserPartNumber')}</DraggableBox>
<DraggableBox name="arrowPartNumber">{getChildrenByName('arrowPartNumber')}</DraggableBox>
<DraggableBox name="tmePartNumber">{getChildrenByName('tmePartNumber')}</DraggableBox>
<DraggableBox name="location">{getChildrenByName('location')}</DraggableBox>
<DraggableBox name="binNumber">{getChildrenByName('binNumber')}</DraggableBox>
<DraggableBox name="binNumber2">{getChildrenByName('binNumber2')}</DraggableBox>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export const getChildrenByName = (name) => {
return "Mouser P/N";
case 'arrowPartNumber':
return "Arrow P/N";
case 'tmePartNumber':
return "TME P/N";
case 'location':
return "Location";
case 'binNumber':
Expand Down
1 change: 1 addition & 0 deletions Binner/Binner.Web/Controllers/PrintController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public async Task<IActionResult> PrintLabel(CustomLabelRequest request)
DigiKeyPartNumber = "701-7011-1-ND",
MouserPartNumber = "MS-7011",
ArrowPartNumber = "AR-7011",
TmePartNumber = "TM-7011",
FootprintName = "DIP-20",
SymbolName = "IC1",
ExtensionValue1 = "Custom Value 1",
Expand Down
44 changes: 44 additions & 0 deletions Binner/Library/Binner.Common/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Binner.Common.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Binner.Common.Extensions
{
public static class EnumerableExtensions
{
/// <summary>
/// Order an IEnumerable using natual sort
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static IOrderedEnumerable<T> OrderByNaturalSort<T>(this IEnumerable<T> source, Func<T, string> selector)
{
var max = source
.SelectMany(i => Regex.Matches(selector(i), @"\d+").Cast<Match>().Select(m => (int?)m.Value.Length))
.Max() ?? 0;

return source.OrderBy(i => Regex.Replace(selector(i), @"\d+", m => m.Value.PadLeft(max, '0')));
}

/// <summary>
/// Order a IDictionary using natual sort
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static IOrderedEnumerable<KeyValuePair<TKey, TValue>> OrderByNaturalSort<TKey, TValue>(this IDictionary<TKey, TValue> source, Func<KeyValuePair<TKey, TValue>, string> selector)
{
var max = source
.SelectMany(i => Regex.Matches(selector(i), @"\d+").Cast<Match>().Select(m => (int?)m.Value.Length))
.Max() ?? 0;

return source.OrderBy(i => Regex.Replace(selector(i), @"\d+", m => m.Value.PadLeft(max, '0')));
}
}
}
1 change: 1 addition & 0 deletions Binner/Library/Binner.Common/IO/Printing/LabelGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ private string GetTextValue(LabelBox box, Part part)
text = text.Replace("{digiKeyPartNumber}", Encode(part.DigiKeyPartNumber, urlEncode));
text = text.Replace("{mouserPartNumber}", Encode(part.MouserPartNumber, urlEncode));
text = text.Replace("{arrowNumber}", Encode(part.ArrowPartNumber, urlEncode));
text = text.Replace("{tmeNumber}", Encode(part.TmePartNumber, urlEncode));
text = text.Replace("{location}", Encode(part.Location, urlEncode));
text = text.Replace("{binNumber}", Encode(part.BinNumber, urlEncode));
text = text.Replace("{binNumber2}", Encode(part.BinNumber2, urlEncode));
Expand Down
3 changes: 2 additions & 1 deletion Binner/Library/Binner.Common/Integrations/AliExpressApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace Binner.Common.Integrations
{
public class AliExpressApi : IIntegrationApi
{
private const string BasePath = "/api/v3/parts";
public string Name => "AliExpress";
private const string BasePath = "/api/v3/parts";
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly HttpClient _client;
private readonly AliExpressConfiguration _configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Binner.Common.Integrations.Models;
using System;

namespace Binner.Common.Integrations
{
public class ApiRequiresAuthenticationException : Exception
{
public IApiResponse ApiResponse { get; set; }

public ApiRequiresAuthenticationException(IApiResponse apiResponse)
{
ApiResponse = apiResponse;
}
}
}
1 change: 1 addition & 0 deletions Binner/Library/Binner.Common/Integrations/ArrowApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Binner.Common.Integrations
public partial class ArrowApi : IIntegrationApi
{
private const string BasePath = "";
public string Name => "Arrow";
private readonly ArrowConfiguration _configuration;
private readonly HttpClient _client;
private readonly ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
Expand Down
5 changes: 3 additions & 2 deletions Binner/Library/Binner.Common/Integrations/DigikeyApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace Binner.Common.Integrations
public class DigikeyApi : IIntegrationApi
{
public static readonly TimeSpan MaxAuthorizationWaitTime = TimeSpan.FromSeconds(30);
public string Name => "DigiKey";

#region Regex Matching
private readonly Regex PercentageRegex = new Regex("^\\d{0,4}(\\.\\d{0,4})? *%?$", RegexOptions.Compiled);
Expand Down Expand Up @@ -252,9 +253,9 @@ public async Task<IApiResponse> GetCategoriesAsync()

public Task<IApiResponse> SearchAsync(string partNumber, int recordCount = 25, Dictionary<string, string>? additionalOptions = null) => SearchAsync(partNumber, string.Empty, string.Empty, recordCount, additionalOptions);

public Task<IApiResponse> SearchAsync(string partNumber, string partType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null) => SearchAsync(partNumber, partType, string.Empty, recordCount, additionalOptions);
public Task<IApiResponse> SearchAsync(string partNumber, string? partType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null) => SearchAsync(partNumber, partType, string.Empty, recordCount, additionalOptions);

public async Task<IApiResponse> SearchAsync(string partNumber, string partType, string mountingType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null)
public async Task<IApiResponse> SearchAsync(string partNumber, string? partType, string? mountingType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null)
{
if (!(recordCount > 0)) throw new ArgumentOutOfRangeException(nameof(recordCount));
var authResponse = await AuthorizeAsync();
Expand Down
9 changes: 7 additions & 2 deletions Binner/Library/Binner.Common/Integrations/IIntegrationApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public interface IIntegrationApi
/// </summary>
public bool IsEnabled { get; }

/// <summary>
/// Api name
/// </summary>
public string Name { get; }

/// <summary>
/// Api configuration
/// </summary>
Expand All @@ -37,7 +42,7 @@ public interface IIntegrationApi
/// <param name="recordCount"></param>
/// <param name="additionalOptions"></param>
/// <returns></returns>
Task<IApiResponse> SearchAsync(string partNumber, string partType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null);
Task<IApiResponse> SearchAsync(string partNumber, string? partType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null);

/// <summary>
/// Search for a part
Expand All @@ -48,7 +53,7 @@ public interface IIntegrationApi
/// <param name="recordCount"></param>
/// <param name="additionalOptions"></param>
/// <returns></returns>
Task<IApiResponse> SearchAsync(string partNumber, string partType, string mountingType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null);
Task<IApiResponse> SearchAsync(string partNumber, string? partType, string? mountingType, int recordCount = 25, Dictionary<string, string>? additionalOptions = null);

/// <summary>
/// Get an order by it's orderId
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Binner.Model;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Binner.Common.Integrations
{
public interface IPartInformationProvider
{
Task<PartInformationResults> FetchPartInformationAsync(string partNumber, string partType, string mountingType, string supplierPartNumbers, int userId, ICollection<PartType> partTypes, Part? inventoryPart);
}
}
1 change: 1 addition & 0 deletions Binner/Library/Binner.Common/Integrations/MouserApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Binner.Common.Integrations
public class MouserApi : IIntegrationApi
{
private const string BasePath = "/api/v1";
public string Name => "Mouser";
private readonly MouserConfiguration _configuration;
private readonly HttpClient _client;
private readonly ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
Expand Down
1 change: 1 addition & 0 deletions Binner/Library/Binner.Common/Integrations/NexarApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Binner.Common.Integrations
{
public class NexarApi : IIntegrationApi
{
public string Name => "Nexar";
private readonly OctopartConfiguration _configuration;
private readonly LocaleConfiguration _localeConfiguration;
private readonly IHttpContextAccessor _httpContextAccessor;
Expand Down
1 change: 1 addition & 0 deletions Binner/Library/Binner.Common/Integrations/OctopartApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Binner.Common.Integrations
{
public class OctopartApi : IIntegrationApi
{
public string Name => "Octopart";
public const string BasePath = "/api/v3/parts";
private readonly OctopartConfiguration _configuration;
private readonly HttpClient _client;
Expand Down

0 comments on commit c2a2b49

Please sign in to comment.