Skip to content

Commit

Permalink
feat: add support for field aliases via config spreadsheet in related…
Browse files Browse the repository at this point in the history
… table grid fields
  • Loading branch information
stdavis committed Oct 19, 2023
1 parent d2cdf08 commit d31fe36
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 43 deletions.
38 changes: 32 additions & 6 deletions functions/common/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { array, string } from 'yup';
* 'Map Label Field': string;
* 'Sort Field': string;
* 'Identify Attributes': string;
* 'Result Grid Fields': (string | { name: string; alias: string })[];
* 'Related Tables': string;
* 'Document Search': string;
* 'GRAMA Request': string;
Expand All @@ -31,6 +32,18 @@ import { array, string } from 'yup';
* }} QueryLayerConfig
*/

/**
* @typedef {{
* 'Additional Information': string;
* 'Feature Service': string;
* 'Grid Fields': (string | { name: string; alias: string })[];
* 'OID Field': string;
* 'SGID Table Name': string;
* 'Table Name': string;
* 'Tab Name': string;
* }} RelatedTableConfig
*/

/**
* @typedef {{
* 'Parent Dataset Name': string;
Expand All @@ -44,8 +57,21 @@ import { array, string } from 'yup';
const urlRegex = /https?:\/\//i;
const invalidUrl = '"${value}" must be a valid URL ("{" and "}" are allowed)';

function commaSeparatedStringToArray(value) {
return value.split(',').map((v) => v.trim());
export function transformFields(value) {
const entries = value.split(',').map((v) => v.trim());

return entries.map((entry) => {
const match = entry.match(/^(.*)\(([^()]*(?:\([^()]*\)[^()]*)*)\)$/);

if (match) {
return {
name: match[1].trim(),
alias: match[2].trim(),
};
}

return entry;
});
}

export const fieldConfigs = {
Expand Down Expand Up @@ -132,8 +158,8 @@ export const fieldConfigs = {
},
resultGridFields: {
name: 'Result Grid Fields',
schema: array().of(string()).required(),
transform: commaSeparatedStringToArray,
schema: array().required(),
transform: transformFields,
},
sgidFeatureClassName: {
name: 'SGID Feature Class Name',
Expand Down Expand Up @@ -167,8 +193,8 @@ export const fieldConfigs = {
},
gridFields: {
name: 'Grid Fields',
schema: array().of(string()).required(),
transform: commaSeparatedStringToArray,
schema: array().required(),
transform: transformFields,
},
oidField: {
name: 'OID Field',
Expand Down
48 changes: 48 additions & 0 deletions functions/common/config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, expect, it } from 'vitest';
import { transformFields } from './config';

describe('transformFields', () => {
it('handles a list of plain fields without aliases', () => {
const config = 'one, two,three';

expect(transformFields(config)).toEqual(['one', 'two', 'three']);
});

it('handles a list of fields with aliases', () => {
const config = 'one (1), two (2),three (3)';

expect(transformFields(config)).toEqual([
{
name: 'one',
alias: '1',
},
{
name: 'two',
alias: '2',
},
{
name: 'three',
alias: '3',
},
]);
});

it('handles nested parentheses in aliases', () => {
const config = 'one (1), two (2),three (3 (three))';

expect(transformFields(config)).toEqual([
{
name: 'one',
alias: '1',
},
{
name: 'two',
alias: '2',
},
{
name: 'three',
alias: '3 (three)',
},
]);
});
});
10 changes: 8 additions & 2 deletions functions/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ async function validateRelationshipClasses(
/**
* @param {FieldValidation} fieldValidation
* @param {string[]} serviceFieldNames
* @param {Object} config
* @param {import('./common/config.js').QueryLayerConfig &
* import('./common/config.js').RelatedTableConfig &
* import('./common/config.js').RelationshipClassConfig} config
* @param {string} configName
* @returns {string[] | boolean}
*/
Expand All @@ -299,7 +301,11 @@ export function validateFields(
validationFieldNames = [configValue];
} else {
// must be array
validationFieldNames = configValue?.length ? configValue : [];
validationFieldNames = configValue?.length
? configValue.map((value) =>
typeof value === 'string' ? value : value.name,
)
: [];
}
} else {
configProp = fieldValidation.configProp;
Expand Down
5 changes: 5 additions & 0 deletions functions/configs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe('validateFields', () => {
const serviceFieldNames = ['one'];

expect(
// @ts-ignore
validateFields(fieldValidation, serviceFieldNames, config, tableName),
).toMatchInlineSnapshot(`
[
Expand All @@ -131,6 +132,7 @@ describe('validateFields', () => {
const serviceFieldNames = ['one'];

expect(
// @ts-ignore
validateFields(fieldValidation, serviceFieldNames, config, tableName),
).toBe(true);
});
Expand All @@ -142,6 +144,7 @@ describe('validateFields', () => {
const serviceFieldNames = ['one', 'two', 'three'];

expect(
// @ts-ignore
validateFields(fieldValidation, serviceFieldNames, config, tableName),
).toBe(true);
});
Expand All @@ -150,6 +153,7 @@ describe('validateFields', () => {
const serviceFieldNames = ['one'];

expect(
// @ts-ignore
validateFields(fieldValidation, serviceFieldNames, config, tableName),
).toBe(true);

Expand All @@ -159,6 +163,7 @@ describe('validateFields', () => {
};

expect(
// @ts-ignore
validateFields(fieldValidation2, serviceFieldNames, config, tableName),
).toBe(true);
});
Expand Down
4 changes: 3 additions & 1 deletion src/components/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,9 @@ export default function MapComponent() {
const query = featureLayer.createQuery();
query.where = featureLayer.definitionExpression;
query.outFields = [
...layer[fieldNames.queryLayers.resultGridFields],
...layer[fieldNames.queryLayers.resultGridFields].map((value) =>
typeof value === 'string' ? value : value.name,
),
featureServiceJson.objectIdField || 'OBJECTID',
];
query.returnGeometry = false;
Expand Down
16 changes: 7 additions & 9 deletions src/components/RelatedRecords.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as Tabs from '../utah-design-system/Tabs';
import { useQuery } from '@tanstack/react-query';
import Spinner from '../utah-design-system/Spinner';
import ky from 'ky';
import { getConfigByTableName } from '../utils';
import { getAlias, getConfigByTableName } from '../utils';
import SimpleTable from '../utah-design-system/SimpleTable';
import { useCallback, useEffect, useState } from 'react';
import Tag from './Tag';
Expand Down Expand Up @@ -116,18 +116,16 @@ function TabContent({
searchParams: params,
}).json();

const oidField = featureServiceJson.objectIdField || 'OBJECTID';

return {
childTableName,
tabName: childConfig[fieldNames.relatedTables.tabName],
rows: relatedRecords.features.map((feature) => feature.attributes),
columns: featureServiceJson.fields
.filter((field) => field.name !== oidField)
.map((field) => ({
Header: field.alias,
accessorKey: field.name,
})),
columns: childConfig[fieldNames.relatedTables.gridFields].map(
(value) => ({
header: value.alias || getAlias(value, featureServiceJson.fields),
accessorKey: value.name || value,
}),
),
};
}

Expand Down
7 changes: 4 additions & 3 deletions src/components/ResultTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ export default function ResultTable({

const columns = useMemo(
() =>
// field could be a string or object
queryLayerResult[fieldNames.queryLayers.resultGridFields].map(
(field) => ({
accessorKey: field,
header: getAlias(field, queryLayerResult.fields),
(value) => ({
accessorKey: value.name || value,
header: value.alias || getAlias(value, queryLayerResult.fields),
}),
),
[queryLayerResult],
Expand Down
1 change: 1 addition & 0 deletions src/components/search-wizard/QueryLayer.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const config = {
'Identify Attributes':
'SYSFACID (System-Facility ID), SYSNUMBER (System Number), SYSNAME (System Name), FACID (Facility Identifier), FACNAME (Facility Name), FACTYPEDESC (Facility Type Description), FACTYPECODE (Facility Type Code), FACACTIVITY (Facility Activity Status), SYSTYPE (System Type), SYSACTIVITY (System Activity Status), SYSPOPULATION (System Population), SYSPOPWHSALE (System Wholesale Population), SYSPHONE (System Phone), SYSPHONEEXT (System Phone Extension), SYSADDRESS1 (System Address1), SYSADDRESS2 (System Address2), SYSCITY (System City), SYSSTATE (System State), SYSZIP (System ZIP Code)\\n',
'Related Tables': 'None',
'Result Grid Fields': [],
'Document Search':
'http://168.178.6.56/TabsPage.aspx?AI_PageConfigID=100001&DivName=DDW',
'GRAMA Request':
Expand Down
1 change: 1 addition & 0 deletions src/components/search-wizard/filters/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe('getWhere', () => {
'Sort Field': '',
'Identify Attributes': '',
'Related Tables': '',
'Result Grid Fields': [],
'Document Search': '',
'GRAMA Request': '',
'Permit Information': '',
Expand Down
22 changes: 0 additions & 22 deletions src/utah-design-system/SimpleTable.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,91 +184,69 @@ const data = [
];
const columns = [
{
Header: 'FACILITYID',
accessorKey: 'FACILITYID',
},
{
Header: 'TANKID',
accessorKey: 'TANKID',
},
{
Header: 'ALTTANKID',
accessorKey: 'ALTTANKID',
},
{
Header: 'FEDERALREG',
accessorKey: 'FEDERALREG',
},
{
Header: 'ABOVETANK',
accessorKey: 'ABOVETANK',
},
{
Header: 'REGAST',
accessorKey: 'REGAST',
},
{
Header: 'TANKEMERGE',
accessorKey: 'TANKEMERGE',
},
{
Header: 'TANKSTATUS',
accessorKey: 'TANKSTATUS',
},
{
Header: 'TANKCAPACI',
accessorKey: 'TANKCAPACI',
},
{
Header: 'SUBSTANCED',
accessorKey: 'SUBSTANCED',
},
{
Header: 'SUBSTANCET',
accessorKey: 'SUBSTANCET',
},
{
Header: 'TANKMATDES',
accessorKey: 'TANKMATDES',
},
{
Header: 'TANKMODSDE',
accessorKey: 'TANKMODSDE',
},
{
Header: 'PIPEMATDES',
accessorKey: 'PIPEMATDES',
},
{
Header: 'PIPEMODDES',
accessorKey: 'PIPEMODDES',
},
{
Header: 'DATEINSTAL',
accessorKey: 'DATEINSTAL',
},
{
Header: 'DATECLOSE',
accessorKey: 'DATECLOSE',
},
{
Header: 'CLOSURESTA',
accessorKey: 'CLOSURESTA',
},
{
Header: 'INCOMPLIAN',
accessorKey: 'INCOMPLIAN',
},
{
Header: 'PST_FUND',
accessorKey: 'PST_FUND',
},
{
Header: 'OTHERTYPE',
accessorKey: 'OTHERTYPE',
},
{
Header: 'FORKLIFT_HASH',
accessorKey: 'FORKLIFT_HASH',
},
];
Expand Down

0 comments on commit d31fe36

Please sign in to comment.