Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move and refactor filters component #80

Merged
merged 1 commit into from
May 13, 2024
Merged

Move and refactor filters component #80

merged 1 commit into from
May 13, 2024

Conversation

JSReds
Copy link
Contributor

@JSReds JSReds commented Mar 29, 2024

!CHANGE DEPENDENCY BEFORE MERGE!

Depends-on: balena-io-modules/ui-shared-components#89

Change-type: major

Screenshot 2024-04-16 at 16 10 24 Screenshot 2024-04-16 at 16 10 33 Screenshot 2024-04-16 at 16 10 36 Screenshot 2024-04-16 at 18 32 10 Screenshot 2024-04-16 at 16 10 12 Screenshot 2024-04-16 at 16 10 21

RENDITION LINES OF CODE:

/Filters
.tsx 1542
.ts 1644

/DataTypes
.ts 198
.tsx 1002

@JSReds JSReds mentioned this pull request Mar 29, 2024
@JSReds JSReds changed the title INIT Move and refactor filters component Apr 16, 2024
@JSReds JSReds self-assigned this Apr 16, 2024
refScheme;
};

export const refSchemePrefix = (schema: JSONSchema) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: getRefSchemePrefix? Seeing as you use refSchemePrefix as a parameter name elsewhere

Comment on lines +158 to +173
return schema.items
? 'items.properties.'
: schema.properties
? 'properties.'
: '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is '' possible?

Tiny nit for readability: perhaps trade the ternaries for ifs? Totally fine if you prefer it this way, just mentioning it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice 😮
What about escape?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added, thanks for pointing out

views?: FiltersView[];
onFiltersChange?: (filters: JSONSchema[]) => void;
onViewsChange?: (views: FiltersView[]) => void;
renderMode?: FilterRenderMode | FilterRenderMode[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to be addressed during this PR, but I'm not quite happy with this property.

AssignDialog uses search and summary, however the user can still click the summary filters to change them into basically the same thing add does. Which means all we are excluding is views. Then DeviceLogs has all 4. Meanwhile, AutoUI has one Filter for add, search, and views, and then another Filter for summary.

So effectively what we amount to is we use all for all instances of Filters except the AssignDialog, for which we want to exclude views and the ability to add non-full-text-search filters (bugged atm), and for AutoUI, the main owner of filters, uses them in pieces instead of as a whole.

We should revisit this later for two things:

  • The bug we see in AssignDialog where we hide add but can still access it via summary
  • Analyzing whether we can reduce this to a single usecase

It's possible that whatever we choose to replace AutoUI will take care of this 🤞

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I also would like to remove some of the properties, for sure we can rethink renderMode, AutoUI has a limitation which is, having the summary in the same FIlters components make it really ugly to handle unfortunately. While doing it I also thought that we might soon switch to something different like a sidebar instead of having this filters view. If we rethink the graphics and the way we display them, we can even just remove some of these properties. It would be very nice

onChange,
InputProps,
...textFieldProps
}: SearchProps & Material.TextFieldProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include this among the SearchProps interface? 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextFieldProps type from Material uses conditional types based on the variant of the text field (filled, standard, outlined).
This force us to define Varinat = 'standard' ... it might be cleaner anyway 🤔
yep, changing it 👍

Comment on lines 123 to 149
if (isJSONSchema(schemaOrProperties) && schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'],
};
}
if (isJSONSchema(schemaOrProperties) && schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
),
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
if (isJSONSchema(schemaOrProperties) && schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'],
};
}
if (isJSONSchema(schemaOrProperties) && schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
),
};
}
if (isJSONSchema(schemaOrProperties)) {
if (schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'],
};
}
if (schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
),
};
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 don't know why I've repeated it... I just had to move it on top, changed it to so that it is not nested

Comment on lines 236 to 251
if (isJSONSchema(f) && f.anyOf) {
return recursivelyRemoveSeparators(f);
}
if (!isJSONSchema(f) || !f.properties) {
return f;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
if (isJSONSchema(f) && f.anyOf) {
return recursivelyRemoveSeparators(f);
}
if (!isJSONSchema(f) || !f.properties) {
return f;
}
if (isJSONSchema(f) {
if (f.anyOf) {
return recursivelyRemoveSeparators(f);
}
} else {
if (!f.properties) {
return f;
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me think about this, as I'm really against nested if, they make the readability really complex for not reason

Comment on lines 137 to 149
// If the current level is a JSON schema and has properties, recursively apply the transformation to these properties.
if (schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'], // Recurse into properties.
};
}
// If the current level is a JSON schema and has an items definition, apply the transformation to the items.
if (schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
), // Recurse into items.
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If the current level is a JSON schema and has properties, recursively apply the transformation to these properties.
if (schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'], // Recurse into properties.
};
}
// If the current level is a JSON schema and has an items definition, apply the transformation to the items.
if (schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
), // Recurse into items.
};
}
if (schemaOrProperties.properties || schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
properties: constructSchemaProperties(
schemaOrProperties.properties ?? (schemaOrProperties.items as JSONSchema),
restRefScheme,
description,
) as JSONSchema['properties'],
};
}

(keep comments of course, I just removed them for the sake of showing purely the suggestion)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the point but we need to change properties and items in the returned object. Also, the as is different as 1 represent JSONSchema['properties'] and the other JSONSchema['items'].

🤔 we can for sure reduce the code, I just would like to avoid adding complexity. Let me give it a try

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could do something like this:

  if (schemaOrProperties.properties || schemaOrProperties.items) {
    const properties = schemaOrProperties.properties
      ? (constructSchemaProperties(
          schemaOrProperties.properties,
          restRefScheme,
          description
        ) as JSONSchema["properties"])
      : undefined;
    const items: JSONSchema["items"] = schemaOrProperties.items
      ? constructSchemaProperties(
          schemaOrProperties.items as JSONSchema,
          restRefScheme,
          description
        )
      : undefined;
    return {
      ...schemaOrProperties,
      title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
      description, // Apply the new description.
      properties, // Recurse into properties.
      items, // Recurse into items.
    };
  }

WDYT ? would you find it more readable or nicer ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the redundancy. Also I realized I made a mistake in my earlier suggestion, fixed here, though we need to do the cast:

Suggested change
// If the current level is a JSON schema and has properties, recursively apply the transformation to these properties.
if (schemaOrProperties.properties) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
properties: constructSchemaProperties(
schemaOrProperties.properties,
restRefScheme,
description,
) as JSONSchema['properties'], // Recurse into properties.
};
}
// If the current level is a JSON schema and has an items definition, apply the transformation to the items.
if (schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title, // Use provided title or default to existing title.
description, // Apply the new description.
items: constructSchemaProperties(
schemaOrProperties.items as JSONSchema,
restRefScheme,
description,
), // Recurse into items.
};
}
if (schemaOrProperties.properties || schemaOrProperties.items) {
return {
...schemaOrProperties,
title: title ?? schemaOrProperties.title,
description,
[schemaOrProperties.properties ? 'properties' : 'items']: constructSchemaProperties(
schemaOrProperties.properties ?? (schemaOrProperties.items as JSONSchema),
restRefScheme,
description,
),
};
}

I just would like to avoid adding complexity

This doesn't really feel complex IMO 😓 What do you find complex about it?

WDYT ? would you find it more readable or nicer ?

If my suggestion doesn't work, this is better than nothing

val,
key,
propKey,
// TODO: replace with the new method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left over... there is no new method at the end, I've tried but it was becoming insanely unreadable 😢

Comment on lines 253 to 255
const refScheme = parseDescriptionProperty(schema, 'x-ref-scheme') as
| string
| null;
Copy link
Contributor

@myarmolinsky myarmolinsky Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast sounds very wrong, especially since string is not a return type of parseDescriptionProperty

Why do we do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just very wrong as you said 😅

Comment on lines 256 to 258
return refScheme
? (get(schema, `${refSchemePrefix}${refScheme}`) as JSONSchema) ?? schema
: schema;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work?

Suggested change
return refScheme
? (get(schema, `${refSchemePrefix}${refScheme}`) as JSONSchema) ?? schema
: schema;
return (get(schema, `${refSchemePrefix}${refScheme}`) as JSONSchema | null) ?? schema;

(added the | null to the cast too because it has to be able to be nullish for ?? to trigger)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work?

Because if !refScheme then ${refSchemePrefix}${refScheme} = ${refSchemePrefix}undefined which shouldn't exist right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another very wrong left over, thanks for pointing it out

Comment on lines 265 to 267
return json && ('x-foreign-key-scheme' in json || 'x-ref-scheme' in json)
? json['x-foreign-key-scheme'] ?? json['x-ref-scheme']
: null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work?

Suggested change
return json && ('x-foreign-key-scheme' in json || 'x-ref-scheme' in json)
? json['x-foreign-key-scheme'] ?? json['x-ref-scheme']
: null;
return json?.['x-foreign-key-scheme'] ?? json?.['x-ref-scheme'] ?? null;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, yep now that I've added al checks and types it works 👍

@JSReds JSReds force-pushed the migrate-filters-to-MUI branch 2 times, most recently from 87cb7e1 to 10d19c7 Compare April 18, 2024 14:43
</Box>
) : (
<FocusContent>
{filteredFittingSearchTerms?.map((entity) => (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{filteredFittingSearchTerms?.map((entity) => (
{filteredFittingSearchTerms.map((entity) => (

Comment on lines +30 to +31
!!find(schema.properties!, { description: 'key' }) ||
!!find(schema.properties!, { description: 'value' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unite into 1 find?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also lodash has may be more appropriate here given how we're using it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this cannot be unified in 1 check as this is finding a description in a nested object:

properties: {
						tag_key: {
							title: 'Tag name',
							description: 'key',
							type: 'string',
						},
						value: {
							title: 'Tag value',
							description: 'value',
							type: 'string',
						},
					},

Also note that _.has is not suitable for this purpose as it is intended to verify if a provided path exists within an object.

we need to use _.find to make sure we find the first description field and check the value in a nested case.

Comment on lines +125 to +133
schema.properties[firstKeyOfValue]
) {
const property = schema.properties[firstKeyOfValue];

// Ensure the property is an object and has a title
if (typeof property === 'object' && property.title) {
return property.title;
}
}
Copy link
Contributor

@myarmolinsky myarmolinsky Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
schema.properties[firstKeyOfValue]
) {
const property = schema.properties[firstKeyOfValue];
// Ensure the property is an object and has a title
if (typeof property === 'object' && property.title) {
return property.title;
}
}
typeof schema.properties[firstKeyOfValue] === 'object' && !!schema.properties[firstKeyOfValue].title
) {
return schema.properties[firstKeyOfValue].title;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not valid, unfortunately.

in case of schema.properties[firstKeyOfValue], TypeScript evaluates it anew, so TypeScript narrows the type for each specific occurrence.

In the case where we assign it to a const, TypeScript infers the type of property at the time of assignment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did anything change here? Revert if not?

@JSReds JSReds force-pushed the migrate-filters-to-MUI branch 2 times, most recently from 2f9d70b to e210f2f Compare April 19, 2024 14:29
@flowzone-app flowzone-app bot enabled auto-merge April 19, 2024 14:34
@JSReds JSReds marked this pull request as draft April 19, 2024 14:47
auto-merge was automatically disabled April 19, 2024 14:47

Pull request was converted to draft

@JSReds JSReds force-pushed the migrate-filters-to-MUI branch 3 times, most recently from 46cc785 to 72545f5 Compare April 22, 2024 16:46
@JSReds JSReds marked this pull request as ready for review May 13, 2024 09:44
@JSReds JSReds requested a review from myarmolinsky May 13, 2024 09:45
@JSReds JSReds requested a review from drskullster May 13, 2024 09:58
@JSReds
Copy link
Contributor Author

JSReds commented May 13, 2024

LGTM

@JSReds JSReds merged commit d8aa80a into main May 13, 2024
44 checks passed
@JSReds JSReds deleted the migrate-filters-to-MUI branch May 13, 2024 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants