-
Notifications
You must be signed in to change notification settings - Fork 33
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
Type Builder v2 Alpha #4442
Type Builder v2 Alpha #4442
Conversation
- Type Builder 2 Base - FE2 parts refactored for reusage on TB2 - Refactor dialogs related to content type (new content, change type) for consistency with new development - Refactored other components for more flexibility and facilitate required features
WalkthroughThe pull request implements extensive refactoring, component removals, and new feature integrations. Updates include adding a new dependency, revising dialog and state properties (replacing properties such as “compact” with “initialCompact”), and streamlining UI components. Numerous new utility hooks, descriptor files, and helper functions have been introduced across content management, forms engine, and various UI modules, along with improved type safety in models and services. Changes
Sequence Diagram(s)sequenceDiagram
participant N as NewContentDialogContainer
participant H as useFetchAllowedTypesForPath
participant S as SelectTypeView
participant D as Dialog UI
N->>H: Request allowed content types for given path
H-->>N: Return { isFetching, contentTypes }
N->>S: Pass content types and initialCompact prop
S->>D: Render dialog with updated type selection view
Note 🎁 Summarized by CodeRabbit FreeYour organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 25
🧹 Nitpick comments (98)
ui/app/src/components/ContentTypeManagement/descriptors/controls/disabled.ts (1)
17-23
: Descriptor Definition and Type Safety Suggestion:
ThedisabledDescriptor
object is clearly defined with the propertiesid
,name
,description
,sections
, andfields
that precisely represent a disabled field control. For stronger type safety and maintainability in the TypeScript environment, consider adding an explicit type annotation (or interface) for descriptors.ui/app/src/components/ContentTypeManagement/components/TypeBuilderAddButton.tsx (1)
19-28
: Clarify or Clean Up Commented Styling Code
There is a TODO along with commented-out styled code. Consider either adding a brief explanation on when or why this custom styling might be re-enabled, or remove the commented code if it isn’t needed anymore. This helps maintain clarity in the codebase.ui/app/src/components/ContentTypeManagement/components/EditTypeViewLayout.tsx (5)
51-51
: Improve ref initialization with proper typing.The
anchorElRef
is initialized withundefined
, which should benull
and should include proper typing for better type safety.- const anchorElRef = useRef(undefined); + const anchorElRef = useRef<HTMLButtonElement | null>(null);
95-96
: Improve accessibility by providing a proper aria-labelledby value.The empty string for aria-labelledby doesn't provide proper accessibility for screen readers.
- slotProps={{ list: { 'aria-labelledby': '' } }} + slotProps={{ list: { 'aria-labelledby': 'content-type-actions-menu' } }}And add an id to the button:
- <IconButton ref={anchorElRef} onClick={handleOpenMenuButton}> + <IconButton id="content-type-actions-menu" ref={anchorElRef} onClick={handleOpenMenuButton}>
33-33
: Consider simplifying the event type.The
MenuItemOrButtonEvent
type is overly complex. Since both event types are React.MouseEvent variants, you can simplify this.- type MenuItemOrButtonEvent = Parameters<MenuItemProps['onClick']>[0] | Parameters<ButtonProps['onClick']>[0]; + type MenuItemOrButtonEvent = React.MouseEvent<HTMLElement>;
40-47
: Optimize the actionsMap definition.The current actionsMap is redundant since keys and values are identical. Consider simplifying or making it more meaningful.
- const actionsMap: Record<EditAppLayoutAction, EditAppLayoutAction> = { - exit: 'exit', - save: 'save', - viewXml: 'viewXml', - diff: 'diff', - history: 'history', - rollback: 'rollback' - }; + // Create an object with EditAppLayoutAction keys and values for data attributes + const actionsMap = Object.fromEntries( + (['exit', 'save', 'viewXml', 'diff', 'history', 'rollback'] as const).map( + action => [action, action] + ) + ) as Record<EditAppLayoutAction, EditAppLayoutAction>;Or, given the redundancy, you might consider simplifying this approach altogether and just use the action strings directly in your data attributes.
17-30
: Consider organizing imports for better maintainability.Group imports by external dependencies, MUI components, and internal components.
+ // React & core imports import React, { forwardRef, useRef, useState } from 'react'; import { FormattedMessage } from 'react-intl'; + // Material UI imports import Box from '@mui/material/Box'; import Tooltip from '@mui/material/Tooltip'; import IconButton, { IconButtonProps } from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import Button, { ButtonProps } from '@mui/material/Button'; import Menu, { MenuProps } from '@mui/material/Menu'; import MenuItem, { MenuItemProps } from '@mui/material/MenuItem'; + // Material UI icons import ArrowBackRounded from '@mui/icons-material/ArrowBackRounded'; import MoreVertRounded from '@mui/icons-material/MoreVertRounded'; + // Internal components & hooks import Layout, { LayoutProps } from './Layout'; import { useShowAlert } from '../../FormsEngine/lib/formUtils';ui/app/src/components/ContentTypeManagement/components/TypeBuilderFormsEngine.tsx (3)
176-195
: Attach handlers to "Move" and "Delete" icons for fields
Currently, the icons only display a tooltip but lack an implementation for the related actions. Consider adding onClick event handlers or methods to perform the intended operations, such as moving or deleting a field.
197-222
: Implement "Swap Field" button functionality
The "Swap Field" icon appears whenfield.type === 'file-name'
, but no logic is provided for swapping fields. If this is intentional, consider adding a “TODO” comment or an onClick handler to clarify future plans.
267-279
: Provide a fallback return inpickPanelTitleByMode
If none of the conditions are met, the function returnsundefined
. Consider providing a default return to avoid potential rendering issues.ui/app/src/components/ContentTypeManagement/components/TypeCardMedia.tsx (1)
1-70
: Well structured and implemented component.The TypeCardMedia component is well-designed for displaying content type preview images with proper loading states. The use of useEffect for image fetching with proper cleanup in the return function demonstrates good React practices.
A few minor suggestions to improve robustness:
- Consider adding error handling to the fetchPreviewImage subscription to handle potential failed image requests
- The ref initialization could use null instead of undefined to better align with React's typing:
useRef<HTMLImageElement>(null)
- const elementRef = useRef<HTMLImageElement>(undefined); + const elementRef = useRef<HTMLImageElement>(null); useEffect(() => { if (!typeId) return; - const sub = fetchPreviewImage(siteId, typeId).subscribe((response) => { - const img = elementRef.current; - const imgUrl = URL.createObjectURL(new Blob([response.response])); - img.src = imgUrl; - img.onload = () => { - // Image has loaded, revoke the object URL to free memory. - URL.revokeObjectURL(imgUrl); - }; - }); + const sub = fetchPreviewImage(siteId, typeId).subscribe({ + next: (response) => { + const img = elementRef.current; + if (img) { + const imgUrl = URL.createObjectURL(new Blob([response.response])); + img.src = imgUrl; + img.onload = () => { + // Image has loaded, revoke the object URL to free memory. + URL.revokeObjectURL(imgUrl); + }; + } + }, + error: (error) => { + console.error('Error fetching preview image:', error); + } + });ui/app/src/hooks/useResizeObserver.ts (1)
22-36
: Consider enhancing the resize observer callback with size informationThe hook correctly sets up the ResizeObserver and handles cleanup, but currently it only notifies that a resize occurred without providing the actual dimensions of the element. This limits the hook's utility.
Consider passing the dimensions to the callback function:
-export function useResizeObserver(containerRef: RefObject<HTMLElement>, observer: () => void, delay = 300): void { +export function useResizeObserver(containerRef: RefObject<HTMLElement>, observer: (entry?: ResizeObserverEntry) => void, delay = 300): void { const refs = useUpdateRefs({ observer, delay }); useLayoutEffect(() => { if (containerRef.current) { const resize$ = new Subject<void>(); - const resizeObserver = new ResizeObserver(() => resize$.next()); + const resizeObserver = new ResizeObserver((entries) => resize$.next(entries[0])); - const subscription = resize$.pipe(debounceTime(delay)).subscribe(() => refs.current.observer()); + const subscription = resize$.pipe(debounceTime(delay)).subscribe((entry) => refs.current.observer(entry)); resizeObserver.observe(containerRef.current); return () => { resizeObserver.disconnect(); subscription.unsubscribe(); }; } }, [delay, containerRef, refs]); }ui/app/src/components/ContentTypeManagement/components/TypeList.tsx (2)
43-48
: Improve null handling in conditional renderingThe first condition can be simplified, and the second condition needs better null handling to prevent potential errors.
- if (!skeleton && !contentTypes) { + if (!skeleton && !contentTypes) { return <></>; } - if (!skeleton && contentTypes?.length === 0) { + if (!skeleton && Array.isArray(contentTypes) && contentTypes.length === 0) { return <EmptyState title={<FormattedMessage defaultMessage="No content types available for display." />} />; }
64-64
: Consider using theme variables for selected item stylingHardcoding the styling for selected cards reduces maintainability and theme consistency.
- sx={[isSelected && { border: `2px solid ${palette.blue.tint}`, opacity: 0.7, boxShadow: 0 }]} + sx={[isSelected && (theme) => ({ + border: `2px solid ${theme.palette.primary.main}`, + opacity: 0.7, + boxShadow: 0 + })]}ui/app/src/utils/object.ts (1)
80-91
: Add warning about non-unique values in reverseLookupTableThe utility function is well-implemented, but it assumes values in the original object are unique, which might lead to data loss.
/** - * { K: V } => { V: K } + * Transforms an object by swapping its keys and values. + * { K: V } => { V: K } + * + * Note: If multiple keys map to the same value in the original object, + * only one entry will be preserved in the reversed object. **/ export function reverseLookupTable<K extends string | number | symbol, V extends string | number | symbol>( original: Record<K, V> ): Record<V, K> {ui/app/src/hooks/useFetchAllowedTypesForPath.tsx (1)
53-57
: Return structure is straightforward and clean.
The returned{ isFetching, contentTypes }
is nicely minimal, simplifying consumer usage. Make sure to include adequate test coverage for scenarios with no content types returned.ui/app/src/components/SearchBar/SearchBar.tsx (1)
164-171
: Flexible ref assignment is well-handled.
The logic correctly handles both callback and object refs, ensuring robust integration. Be mindful if you ever need to support multiple refs; consider a library likeuseMergedRef
if that arises.ui/app/src/utils/path.ts (1)
283-283
: Good documentation for future refactoring.The TODO comment correctly identifies the duplication between
stripDuplicateSlashes
andensureSingleSlash
functions. This is helpful for future code cleanup.Consider consolidating these duplicate functions in a future cleanup to improve maintainability. When you do, ensure you update all references to use a single function.
ui/app/src/components/ResizeableDrawer/ResizeableDrawer.tsx (1)
118-120
: UI adjustment with good documentation.Changing the top value from 65 to 57 pixels will adjust the vertical positioning of the drawer when below the toolbar. The TODO comment is valuable as it recommends making this value a global constant rather than having it hardcoded in multiple places.
Consider implementing the TODO sooner rather than later by creating a global constant for toolbar height in a theme or constants file. This would improve maintainability by centralizing this value and making future UI adjustments easier.
ui/app/src/components/ContentTypeManagement/descriptors/controls/localeSelector.ts (2)
18-18
: Consider using a more descriptive name for validation objectThe imported
foo
variable is an empty frozen object being used for validations. Using a more descriptive name likeemptyValidation
ornoValidation
would make the code more self-documenting.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidation } from '../../../../utils/object';And then update its usage accordingly.
29-35
: Consider extracting common field patternsBoth "readonly" and "required" fields follow identical patterns with the same field type and structure. Consider creating a helper function to generate these common checkbox fields to reduce duplication across descriptor files.
// In a shared utils file: +export function createCommonBooleanField(id: string, name: string) { + return { + id, + type: 'checkbox', + name, + defaultValue: undefined, + validations: foo + }; +} // In this file: - fields: { - readonly: { - id: 'readonly', - type: 'checkbox', - name: 'Read Only', - defaultValue: undefined, - validations: foo - }, - required: { - id: 'required', - type: 'checkbox', - name: 'Required', - defaultValue: undefined, - validations: foo - } - } + fields: { + readonly: createCommonBooleanField('readonly', 'Read Only'), + required: createCommonBooleanField('required', 'Required') + }Also applies to: 36-42
ui/app/src/components/ContentTypeManagement/descriptors/controls/label.ts (2)
20-34
: Add explicit typing for consistency with other descriptorsFor consistency with other descriptor files (like localeSelector.ts), consider explicitly typing
labelDescriptor
asPartialContentType
.-export const labelDescriptor = { +import { PartialContentType } from '../../utils'; +export const labelDescriptor: PartialContentType = {
18-18
: Consider using a more descriptive name for validation objectSimilar to the localeSelector file, the imported
foo
variable is an empty frozen object used for validations. A more descriptive name would improve code clarity.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidation } from '../../../../utils/object';ui/app/src/components/ContentTypeManagement/descriptors/controls/autoFileName.ts (2)
20-44
: Consider reducing duplication with localeSelector descriptorThe structure of this descriptor is almost identical to the localeSelector descriptor, with only the id, name, and description being different. Consider extracting a factory function to create these similar descriptors and reduce code duplication.
// In a shared utils file: +export function createBasicControlDescriptor( + id: string, + name: string, + description: string +): PartialContentType { + return { + id, + name, + description, + sections: [ + createVirtualSection({ title: 'Options', fields: ['readonly'] }), + createVirtualSection({ title: 'Constraints', fields: ['required'] }) + ], + fields: { + readonly: { + id: 'readonly', + type: 'checkbox', + name: 'Read Only', + defaultValue: undefined, + validations: foo + }, + required: { + id: 'required', + type: 'checkbox', + name: 'Required', + defaultValue: undefined, + validations: foo + } + } + }; +} // In this file: -export const autoFileNameDescriptor: PartialContentType = { - id: 'auto-filename', - name: 'Auto Filename', - description: 'Automatically generated filename', - sections: [ - createVirtualSection({ title: 'Options', fields: ['readonly'] }), - createVirtualSection({ title: 'Constraints', fields: ['required'] }) - ], - fields: { - readonly: { - id: 'readonly', - type: 'checkbox', - name: 'Read Only', - defaultValue: undefined, - validations: foo - }, - required: { - id: 'required', - type: 'checkbox', - name: 'Required', - defaultValue: undefined, - validations: foo - } - } -}; +export const autoFileNameDescriptor: PartialContentType = createBasicControlDescriptor( + 'auto-filename', + 'Auto Filename', + 'Automatically generated filename' +);
18-18
: Consider using a more descriptive name for validation objectSimilar to the other descriptor files, the imported
foo
variable name doesn't clearly convey its purpose as an empty validation object.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidation } from '../../../../utils/object';ui/app/src/components/ContentTypeManagement/descriptors/controls/time.ts (2)
17-18
: Import naming could be improved for clarityThe import of
foo
from the object utility seems to be a non-descriptive name for what appears to be an empty validation object. Consider renaming this import to better reflect its purpose, such asemptyValidation
ornoValidations
.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidations } from '../../../../utils/object';
20-44
: Consider adding type annotation for consistencyThe
timeDescriptor
constant lacks a type annotation, unlike some other similar descriptors (likelinkInputDescriptor
) that are explicitly typed asPartialContentType
. Adding a type annotation would improve type safety and consistency.-export const timeDescriptor = { +export const timeDescriptor: PartialContentType = {ui/app/src/components/ContentTypeManagement/descriptors/controls/checkbox.ts (3)
17-18
: Import naming could be improved for clarityThe import of
foo
from the object utility seems to be a non-descriptive name for what appears to be an empty validation object. Consider renaming this import to better reflect its purpose, such asemptyValidation
ornoValidations
.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidations } from '../../../../utils/object';
20-44
: Consider adding type annotation for consistencyThe
checkboxDescriptor
constant lacks a type annotation, unlike some other similar descriptors (likelinkInputDescriptor
) that are explicitly typed asPartialContentType
. Adding a type annotation would improve type safety and consistency.-export const checkboxDescriptor = { +export const checkboxDescriptor: PartialContentType = {
1-46
: Consider extracting a factory function for descriptorsThere's significant repetition across descriptor files with identical sections and field structures. Consider creating a factory function to generate these descriptors with common elements, reducing duplication.
// Example factory function function createSimpleControlDescriptor(id: string, name: string, description: string): PartialContentType { return { id, name, description, sections: [ createVirtualSection({ title: 'Options', fields: ['readonly'] }), createVirtualSection({ title: 'Constraints', fields: ['required'] }) ], fields: { readonly: { id: 'readonly', type: 'checkbox', name: 'Read Only', defaultValue: undefined, validations: foo }, required: { id: 'required', type: 'checkbox', name: 'Required', defaultValue: undefined, validations: foo } } }; }ui/app/src/components/ContentTypeManagement/descriptors/controls/linkInput.ts (1)
17-18
: Import naming could be improved for clarityThe import of
foo
from the object utility seems to be a non-descriptive name for what appears to be an empty validation object. Consider renaming this import to better reflect its purpose, such asemptyValidation
ornoValidations
.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidations } from '../../../../utils/object';ui/app/src/components/ContentTypeManagement/descriptors/controls/videoPicker.ts (2)
1-2
: Missing copyright headerUnlike the other descriptor files, this file is missing the standard copyright and license header that's present in the other files. Consider adding the standard header for consistency.
+/* + * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + import { foo } from '../../../../utils/object'; import { createVirtualSection, PartialContentType } from '../../utils';
1-1
: Import naming could be improved for clarityThe import of
foo
from the object utility seems to be a non-descriptive name for what appears to be an empty validation object. Consider renaming this import to better reflect its purpose, such asemptyValidation
ornoValidations
.-import { foo } from '../../../../utils/object'; +import { foo as emptyValidations } from '../../../../utils/object';ui/app/src/components/FormsEngine/lib/formConsts.ts (1)
26-27
: Consider the TODO comment about stackFormCountAtom placement.The comment suggests that
stackFormCountAtom
should be defined in GlobalFormContext. As part of this refactoring effort, it would be beneficial to address this TODO and move the atom to its proper location.ui/app/src/components/ContentTypeManagement/descriptors/controls/repeat.ts (1)
24-27
: Consider adding constraints to ensure minOccurs ≤ maxOccurs.When using a repeating group, there should be validation to ensure that the minimum occurrences is less than or equal to the maximum occurrences.
Consider adding cross-field validation or UI guidance to enforce this constraint:
createVirtualSection({ title: 'Options', fields: ['minOccurs', 'maxOccurs', 'readonly'] }), +// Add helper text or validation logic to ensure minOccurs ≤ maxOccurs
ui/app/src/components/ContentTypeManagement/descriptors/controls/imagePicker.ts (1)
31-67
: Add meaningful validation and default values to image picker fields.The descriptor fields use undefined default values and empty validation objects. For numeric fields like
thumbnailWidth
andthumbnailHeight
, consider adding reasonable defaults and validation rules.Example improvements:
thumbnailWidth: { id: 'thumbnailWidth', type: 'numeric-input', name: 'Thumbnail Width', - defaultValue: undefined, - validations: foo + defaultValue: 150, + validations: { + min: 50, + isInteger: true + } }, thumbnailHeight: { id: 'thumbnailHeight', type: 'numeric-input', name: 'Thumbnail Height', - defaultValue: undefined, - validations: foo + defaultValue: 150, + validations: { + min: 50, + isInteger: true + } },ui/app/src/components/ContentTypeManagement/descriptors/controls/textarea.ts (2)
29-71
: Add meaningful validation and default values to textarea fields.The fields in this descriptor use undefined default values and empty validation objects. Consider adding reasonable defaults and validation rules for numeric fields like height, width, and maxlength.
Example improvements:
height: { id: 'height', type: 'numeric-input', name: 'Height', - defaultValue: undefined, - validations: foo + defaultValue: 100, + validations: { + min: 20, + isInteger: true + } }, width: { id: 'width', type: 'numeric-input', name: 'Width', - defaultValue: undefined, - validations: foo + defaultValue: 300, + validations: { + min: 50, + isInteger: true + } }, maxlength: { id: 'maxlength', type: 'numeric-input', name: 'Maximum Length', - defaultValue: undefined, - validations: foo + defaultValue: 1000, + validations: { + min: 1, + isInteger: true + } },
57-63
: Add a helpful description for the tokenize field.The "Tokenize for Indexing" field might not be immediately clear to all users. Consider adding a description property to explain its purpose.
tokenize: { id: 'tokenize', type: 'checkbox', name: 'Tokenize for Indexing', defaultValue: undefined, validations: foo, + description: 'When enabled, the text content will be processed for search indexing' },
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkedDropdown.ts (2)
17-18
: Consider absolute imports for better maintainability.The deep relative imports (
'../../utils'
and'../../../../utils/object'
) can be difficult to maintain if files are moved. Consider using absolute imports (e.g.,'src/components/ContentTypeManagement/utils'
) for better maintainability.
28-57
: Consider adding meaningful validations instead of empty object.The
foo
object used for validations is currently an empty frozen object. While this works as a placeholder, consider implementing actual validation rules for these fields to ensure data integrity.Also, all fields have
defaultValue: undefined
. Consider providing appropriate default values where applicable (e.g.,false
for checkboxes) to improve the user experience.- validations: foo + validations: { + // Add appropriate validation rules + } - defaultValue: undefined + defaultValue: false // For boolean fields like readonly/requiredui/app/src/components/ContentTypeManagement/descriptors/controls/numericInput.ts (1)
43-56
: Consider adding relationship validation between minValue and maxValue.The
minValue
andmaxValue
fields should have a relationship constraint to ensureminValue
is always less than or equal tomaxValue
. Consider implementing this validation to prevent potential invalid configurations.maxValue: { id: 'maxValue', type: 'numeric-input', name: 'Maximum Value', defaultValue: undefined, - validations: foo + validations: { + // Add validation to ensure maxValue is greater than or equal to minValue + } }ui/app/src/components/ContentTypeManagement/descriptors/controls/dropdown.ts (3)
20-24
: Add type annotation for consistency with other descriptors.Unlike other descriptors,
dropdownDescriptor
lacks a type annotation. Consider adding: PartialContentType
to maintain consistency with the other descriptor files.- export const dropdownDescriptor = { + export const dropdownDescriptor: PartialContentType = {
29-35
: Define structure for repeat field options.The
options
field is of typerepeat
but doesn't specify the structure for each repeated item. Consider defining a clear structure for dropdown options (e.g., label/value pairs) to ensure consistent data entry.
43-49
: Consider providingtrue
as defaultValue for allowEmpty.Since most dropdowns should allow users to select nothing by default, consider setting
defaultValue: true
for theallowEmpty
field to improve usability.allowEmpty: { id: 'allowEmpty', type: 'checkbox', name: 'Allow Empty', - defaultValue: undefined, + defaultValue: true, validations: foo }ui/app/src/components/ContentTypeManagement/descriptors/controls/input.ts (3)
40-46
: Inconsistent field name casing.The
readonly
field uses lowercase for thename
property, while other fields use proper capitalization or camelCase. Consider standardizing the naming convention for better UI consistency.readonly: { id: 'readonly', type: 'checkbox', - name: 'readonly', + name: 'Read Only', defaultValue: undefined, validations: foo }
54-60
: Inconsistent field name casing.Similar to the
readonly
field, theescapeContent
field uses camelCase for thename
property without spaces, while other fields use proper spacing or different conventions. Standardize naming for UI consistency.escapeContent: { id: 'escapeContent', type: 'checkbox', - name: 'escapeContent', + name: 'Escape Content', defaultValue: undefined, validations: foo }
68-74
: Add helpful description for pattern field.The
pattern
field is a text input for entering regex patterns, which can be complex for non-technical users. Consider adding a description or placeholder with an example pattern to help users.pattern: { id: 'pattern', type: 'input', name: 'pattern', defaultValue: undefined, + description: 'Regular expression pattern (e.g., [0-9]+ for numbers only)', validations: foo }
ui/app/src/components/FormsEngine/lib/validators.ts (1)
51-52
: Consider consistent value types in validatorsMapThe newly added
colorPicker
entry usesundefined
while all other entries in the map usenull
. While this may be intentional, it creates an inconsistency in the pattern.Consider using
null
for consistency:'video-picker': null, - colorPicker: undefined + colorPicker: nullui/app/src/components/ContentTypeManagement/descriptors/controls/boxFileUpload.ts (2)
22-53
: Consider using a more specific validation objectThe descriptor uses
foo
(an empty frozen object) for all field validations. This might be a placeholder, but for proper validation, you should consider defining more specific validation rules.Consider defining appropriate validation rules for each field type. For example, the "path" field might need format validation.
31-37
: Consider adding a placeholder or format hintThe
path
field could benefit from a placeholder value or format hint to guide users on the expected format for Box file paths.Add a placeholder property to provide guidance:
path: { id: 'path', type: 'input', name: 'Path', defaultValue: undefined, + placeholder: 'e.g., /folder/file.ext', validations: foo },
ui/app/src/components/ContentTypeManagement/descriptors/controls/uuid.ts (2)
20-44
: Add type annotation for consistent typingUnlike the other descriptor files,
uuidDescriptor
doesn't have an explicit type annotation. For consistency and type safety, consider adding thePartialContentType
type.- export const uuidDescriptor = { + export const uuidDescriptor: PartialContentType = { id: 'uuid', name: 'UUID', ...
28-43
: Consider adding helptext for fieldsThe UUID control's fields would benefit from additional helptext to explain their purpose, especially for the 'readonly' field which may not be immediately obvious in the context of a UUID.
Add helptext to provide more context:
readonly: { id: 'readonly', type: 'checkbox', name: 'Read Only', defaultValue: undefined, + helpText: 'When enabled, the UUID cannot be modified after creation', validations: foo },
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkTextarea.ts (2)
20-44
: Consider adding field for maximum linksFor a control that handles multiple URLs/links, it might be useful to add a configuration option for the maximum number of links allowed.
Consider adding a maxLinks field to the Options section:
sections: [ - createVirtualSection({ title: 'Options', fields: ['readonly'] }), + createVirtualSection({ title: 'Options', fields: ['readonly', 'maxLinks'] }), createVirtualSection({ title: 'Constraints', fields: ['required'] }) ], fields: { readonly: { id: 'readonly', type: 'checkbox', name: 'Read Only', defaultValue: undefined, validations: foo }, + maxLinks: { + id: 'maxLinks', + type: 'numeric-input', + name: 'Maximum Links', + defaultValue: undefined, + helpText: 'Maximum number of links allowed (leave empty for unlimited)', + validations: foo + }, required: { // existing code
17-18
: Consider descriptive names for utility importsThe import of
foo
from utils/object is not descriptive of its purpose. Using a more descriptive name would improve code readability.import { createVirtualSection, PartialContentType } from '../../utils'; -import { foo } from '../../../../utils/object'; +import { emptyValidations as foo } from '../../../../utils/object';Alternatively, consider renaming the utility in its source file to better reflect its purpose.
ui/app/src/components/ContentTypeManagement/descriptors/controls/rte.ts (1)
20-65
: Add type annotation for improved type safety.Unlike the other descriptors,
rteDescriptor
is missing thePartialContentType
type annotation. While the structure matches the expected type, adding the explicit type would ensure type safety and consistency with the other descriptor files.-export const rteDescriptor = { +export const rteDescriptor: PartialContentType = {ui/app/src/components/ContentTypeManagement/descriptors/controls/awsFileUpload.ts (3)
17-18
: Consider replacing the ambiguousfoo
import.The import name
foo
is not descriptive and may cause confusion. Consider renaming it to something more meaningful likeemptyValidations
ordefaultValidations
to better reflect its purpose.- import { foo } from '../../../../utils/object'; + import { foo as emptyValidations } from '../../../../utils/object';
20-51
: Good implementation of AWS file upload descriptor.The descriptor is well-structured with appropriate sections for Options and Constraints, following the pattern used for other control descriptors.
Consider adding JSDoc comments for the fields to improve developer understanding of their purpose and expected values.
34-35
: Validations definition needs implementation.The empty frozen object
foo
is used for validations but doesn't provide any actual validation logic. Consider implementing actual validation rules or documenting why an empty object is sufficient.- validations: foo + validations: { + // Add appropriate validation rules for path + }ui/app/src/components/ContentTypeManagement/descriptors/controls/transcodedVideoPicker.ts (2)
17-18
: Consider replacing the ambiguousfoo
import.The import name
foo
is not descriptive and may cause confusion. Consider renaming it to something more meaningful likeemptyValidations
ordefaultValidations
to better reflect its purpose.- import { foo } from '../../../../utils/object'; + import { foo as emptyValidations } from '../../../../utils/object';
20-44
: Good implementation of transcoded video picker descriptor.The descriptor is well-structured with appropriate sections for Options and Constraints, similar to other control descriptors.
Consider adding JSDoc comments for the fields to improve developer understanding of their purpose and expected values.
ui/app/src/components/ContentTypeManagement/descriptors/controls/internalName.ts (1)
31-46
: Consider consistency with other descriptors.The field structure is different from the other descriptors. The
required
field has a default value oftrue
while other descriptors useundefined
. Consider whether this inconsistency is intentional.ui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts (1)
28-64
: Consider adding documentation to field configurations.The field configurations lack comments explaining their purpose and expected values, which would improve maintainability.
Consider adding documentation for each field, especially for the
options
field since it's likely the most complex part of this control. For example:options: { id: 'options', type: 'repeat', name: 'Options', defaultValue: undefined, + description: 'Define available options for the checkbox group', validations: foo },
ui/app/src/components/ContentTypeManagement/descriptors/controls/fileName.ts (1)
29-35
: Inconsistent naming convention.The field naming convention is inconsistent throughout the descriptor.
Standardize the field naming convention:
maxlength: { id: 'maxlength', type: 'numeric-input', - name: 'maxLength', + name: 'Max Length', defaultValue: undefined, validations: foo }, readonly: { id: 'readonly', type: 'checkbox', - name: 'readonly', + name: 'Read Only', defaultValue: undefined, validations: foo },Also applies to: 37-42, 51-56
ui/app/src/components/FormsEngine/components/FormBackToTop.tsx (1)
29-30
: Consider adding a safety check for the containerRef.The component should handle the case when
containerRef.current
is null, which can happen before the ref is attached.export function FormBackToTop({ containerRef, getScrollContainer = (e) => e }: FormBackToTopProps) { + const handleScrollToTop = () => { + const element = containerRef.current; + if (element) { + getScrollContainer(element).scroll({ top: 0, behavior: 'smooth' }); + } + }; return ( <Box minHeight={100} justifyContent="center" alignItems="center" display="flex"> <Tooltip title={<FormattedMessage defaultMessage="Back to top" />}> - <Fab onClick={() => getScrollContainer(containerRef.current).scroll({ top: 0, behavior: 'smooth' })}> + <Fab onClick={handleScrollToTop}> <ArrowUpward /> </Fab> </Tooltip> </Box> ); }ui/app/src/components/ContentTypeManagement/components/MainSection.tsx (1)
20-21
: Consider making this a shared component.The TODO comment correctly identifies that this layout pattern could be reused elsewhere. Since this appears to be a generic drawer layout pattern, consider moving it to a shared components directory instead of keeping it specific to ContentTypeManagement.
ui/app/src/components/FormsEngine/lib/useSaveForm.tsx (1)
119-119
: New TODO for package cancellation.This new comment suggests an upcoming enhancement for the content saving functionality related to package cancellation.
Consider adding a more detailed comment to provide context about when and why packages might need to be canceled during content saving.
ui/app/src/components/ContentTypeManagement/descriptors/controls/forceHttps.ts (1)
17-34
: Consider improving validation and default value for the checkbox fieldThe refactoring to a descriptor-based approach looks good, but there are two concerns:
- The use of
foo
(an empty frozen object) for validations doesn't seem to provide any actual validation logic.- Using
undefined
as a default value for a checkbox field is unusual; typically, checkboxes should have a boolean default.readonly: { id: 'readonly', type: 'checkbox', name: 'Read Only', - defaultValue: undefined, - validations: foo + defaultValue: false, + validations: { + // Add actual validation rules if needed + } }ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx (1)
40-76
: Excellent component implementation with proper state management.The
SelectTypeView
component demonstrates several good practices:
- Uses
useState
for local state management- Implements debounced input for search performance
- Utilizes
useEffect
for derived state calculations- Properly handles prop-to-state initialization
- Implements a clean UI structure with proper component composition
One minor suggestion to improve type safety:
Consider specifying the initial state for
filteredTypes
to avoid the undefined state:-const [filteredTypes, setFilteredTypes] = useState<ContentType[]>(); +const [filteredTypes, setFilteredTypes] = useState<ContentType[]>( + filterTypesByKeywordsAndObjectType(contentTypesList, keywords, objectTypeFilter) +);ui/app/src/components/ContentTypeManagement/components/TypeListingView.tsx (2)
35-35
: Consider providing a more specific type for the event parameterThe
onTypeSelected
callback type is usingParameters<TypeListProps['onCardClick']>[0]
for the event parameter. Consider defining a more explicit type to make it clearer what kind of event is expected.
53-55
: Consider checking for null before accessing propertiesThe line
const loading = contentTypesList == null;
correctly checks for null/undefined, but you should add more comprehensive error handling for when the API call fails to load the content types list.- const contentTypesList = useContentTypeList(); - const loading = contentTypesList == null; + const { data: contentTypesList, error, loading } = useContentTypeList(); + + // Show error state if the API call fails + if (error) { + return <ErrorDisplay message="Failed to load content types" error={error} />; + }ui/app/src/components/FormsEngine/controls/ColorPicker.tsx (4)
59-68
: Add proper TypeScript typing for the CustomHexColorInput componentThe CustomHexColorInput component is missing proper TypeScript props definition. Consider adding an interface for its props.
+interface CustomHexColorInputProps extends ComponentProps<typeof HexColorInput> {} -const CustomHexColorInput = forwardRef((props, ref) => { +const CustomHexColorInput = forwardRef<HTMLInputElement, CustomHexColorInputProps>((props, ref) => {
76-81
: Remove commented codeThere's commented out code that appears to be an earlier implementation. This should be removed to keep the codebase clean.
- // const presetColors = ['#cd9323', '#1a53d8', '#9a2151', '#0d6416', '#8d2808']; - // return ( - // <FormsEngineField field={field}> - // <RgbaColorPicker color={value} onChange={setValue} /> - // </FormsEngineField> - // );
82-83
: Add null check before accessing nested propertiesThe code accesses nested properties without first verifying they exist, which could lead to runtime errors.
- const alpha = (field.properties.alpha.value as boolean) ?? true; - const format = (field.properties.format.value as ColourFormat) ?? 'hex'; + const alpha = (field.properties?.alpha?.value as boolean) ?? true; + const format = (field.properties?.format?.value as ColourFormat) ?? 'hex';
145-154
: Move throttle to a utility fileThe throttle function is a general utility and should be moved to a common utility file instead of being defined in this component file.
Consider moving this to a file like
ui/app/src/utils/function.ts
and importing it here. This would make it reusable across the application.ui/app/src/components/ContentTypeManagement/descriptors/archetypes.ts (1)
19-19
: Consider using a more descriptive variable name than 'foo'.The variable
foo
is an empty frozen object used for validations, but its name is not descriptive of its purpose. A more meaningful name likeemptyValidations
ordefaultValidations
would better communicate its intended use.-import { foo } from '../../../utils/object'; +import { foo as emptyValidations } from '../../../utils/object';ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx (1)
61-61
: Use specific props for Paper component.Instead of spreading
{...slotProps}
directly to the Paper component which might include unrelated properties, explicitly spread onlyslotProps?.paper
to avoid potential issues.-<Paper {...slotProps} sx={consolidateSx({ p: 1, mb: 2, display: 'flex' }, slotProps?.paper?.sx)}> +<Paper {...slotProps?.paper} sx={consolidateSx({ p: 1, mb: 2, display: 'flex' }, slotProps?.paper?.sx)}>ui/app/src/components/ContentTypeManagement/components/TypeDetailsVIewHeader.tsx (3)
36-36
: Fix component name typo.The component name
TypeDetailsVIewHeader
has a typo (capital 'I' in 'VIew'). For consistency and readability, rename it toTypeDetailsViewHeader
.-export function TypeDetailsVIewHeader({ type, onActionClick }: TypeDetailsHeaderProps) { +export function TypeDetailsViewHeader({ type, onActionClick }: TypeDetailsHeaderProps) {Remember to also update the filename and default export accordingly.
45-46
: Remove console.log statement before production.There's a
console.log
statement that should be removed before deploying to production. Consider using a proper logging system if needed.- console.log('Deleted.'); onActionClick?.(e, 'deleted');
69-79
: Implement missing date and user information.The component includes a TODO comment about missing last update date and user information, but uses hardcoded values. This should be addressed by fetching the actual data from the content type.
- // TODO: Where does this come from? Add to XML? - date: 'today', - user: 'John', + date: type.lastModifiedDate ? new Date(type.lastModifiedDate).toLocaleString() : 'N/A', + user: type.lastModifier || 'N/A',Would you like me to propose a more comprehensive solution for tracking and displaying this metadata?
ui/app/src/components/GlobalDialogManager/DialogStackItemContainer.tsx (1)
87-94
: Handle type discrepancy properlyThere's a TODO comment about a type discrepancy between
EnhancedDialogProps['onTransitionExited']
andpropsRef.current.onTransitionEnd
. This should be addressed properly rather than using@ts-expect-error
.Consider either:
- Updating the interface definition to align these types
- Creating a proper type assertion that converts between the types
- Add proper documentation explaining why this discrepancy exists and why the error suppression is necessary
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (2)
36-38
: Consider simplifying with a more versatile implementationThe
composeFieldPath
function only handles two segments. Consider using the commented-out implementation on line 34 which can handle variable numbers of path segments and possibly simplify code that uses this function.-function composeFieldPath(fieldPath: string, fieldId: string): string { - return fieldPath ? `${fieldPath}.${fieldId}` : fieldId; -} +function composeFieldPath(...pieces: string[]): string { + return pieces.filter(Boolean).join('.'); +}
52-149
: Well-structured component with proper error handling and selection statesThe
FieldChip
component is well-implemented with several nice features:
- Properly handles different field types (repeat vs. other types)
- Supports error states via
fieldPathsWithErrors
- Handles selection state with visual feedback
- Recursively renders nested fields for repeat types
- Properly handles dark/light mode theming
There are a couple of minor concerns:
- Type assertions with
as ElementType<BoxProps>
on lines 60-61- The @ts-expect-error comments on lines 97 and 102
Consider refactoring to avoid the type assertions and TypeScript suppressions by creating more precise type definitions or component wrappers.
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx (2)
32-35
: Consider validatingitem
before usage.Currently, this code destructures
props.item
and then immediately usesitem.path
. If there’s any scenario in whichitem
might be undefined or null, this could cause runtime errors. A quick check or assertion before callingwithoutIndex(item.path)
may help avoid potential null reference issues.
44-71
: Optional: Make the skeleton item count configurable.A fixed skeleton count of “4” might work fine in many cases. However, if you plan to reuse this dialog in contexts requiring more or fewer placeholders, consider making the skeleton item count a prop. This adds flexibility without complicating the UI.
ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx (4)
90-94
: Potential performance overhead during bulk expansion/collapse.The
setSectionsExpandedState
function loops over all section atoms and sets them individually, which may be slightly inefficient for a large number of sections. Consider batching state updates or using an optimized approach if performance becomes a concern with more sections.
110-113
: Clarify parameter types forhandleDataSourceSelected
.The callback function
_ => ...
indicates an unused parameter. For clarity and maintainability, consider explicitly naming parameters and providing type annotations (e.g.,(event: React.MouseEvent, field: ContentTypeField) => ...
) to improve readability and reduce confusion when future developers revise or extend this code.
139-168
: Consider user interface for adding fields.Currently, a "Add Field" button is provided for each section, but the actual creation process isn’t outlined in this snippet. Ensuring a clear workflow (e.g., a dialog or inline prompt for field details) will greatly improve usability and completeness of the “Add Field” functionality.
209-218
: Allow user-defined new section title.The
SectionInsertionDialog
always inserts a new section with a hardcoded title ("New Section"). You might consider prompting the user for a custom title, which would improve flexibility. This could be done via an additional text field in the dialog or a subsequent edit flow.ui/app/src/components/ContentTypeManagement/components/CreateTypeDialog.tsx (2)
68-70
: Add custom validation logic.There is a TODO comment regarding validation. Currently, the
validate
function is a placeholder. Before production, ensure proper checks for unique IDs, invalid characters, or type conflicts to prevent creating faulty or duplicate content types.
139-139
: Address the misleading character class warning.Static analysis complains about the
[\\u0300-\\u036f]
character range. This approach may have edge cases with more complex diacritical marks. Consider using a library specifically designed for diacritic stripping or an alternative pattern if you need broader coverage.🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: A character class cannot match a character and a combining character.
A character and a combining character forms a new character. Replace the character class with an alternation.
(lint/suspicious/noMisleadingCharacterClass)
ui/app/src/components/ContentTypeManagement/ContentTypeManagement.tsx (2)
47-51
: Remove accidental or leftover commented lines.The lines containing “dispatch(emitSystemEvent(...))” and “onClose?.()” are commented out. Consider removing them if they are no longer needed or uncommenting them if they serve a valid purpose to avoid confusion.
55-66
: Add a dedicated “create” pathway.The state variable
view
includes'create'
, but there is no corresponding UI flow for this mode. If it’s part of an upcoming feature, add a placeholder route or comment to clarify. Otherwise, remove the redundant value from the union type to keep the codebase clean.ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (2)
53-58
: Unused variable check
ThedataSourceRootProperties
constant is declared but not referenced later in the file. Consider using or removing it to keep the codebase clean.-const dataSourceRootProperties = ['id', 'type', 'title', 'interface']; +// Remove or use this variable if needed: +// const dataSourceRootProperties = ['id', 'type', 'title', 'interface'];
319-396
: Section descriptor & extended fields
ThesectionDescriptor
with a color picker introduces a nice visual enhancement. Fields such asdescription
,expandByDefault
, andcolor
are well-defined. Validations rely onfoo
, but consider adding more robust validations if user input might be malformed.ui/app/src/models/ContentType.ts (1)
70-127
: Extended properties region
The use of a large union of string keys inproperties
is flexible but could become unwieldy. Consider grouping related properties or using narrower, typed fields to catch mistakes at compile time.ui/app/src/components/ContentTypeManagement/components/EditTypeView.tsx (1)
467-477
:updateTypeFromSectionUpdate()
Creates a shallow copy and updates the matching section by index. The console logging can remain for debugging but consider removing or gating it based on environment.console.log(index, selectedSection, updatedValues, updatedType); -// Consider removing or wrapping in a condition if there's a risk of polluting logs in production
ui/app/src/services/contentTypes.ts (1)
103-115
: Consider parseFloat edge cases.
bestGuessParse()
treats any partial numeric string (e.g.,"123abc"
) as a valid float. Verify that this behavior is desired or consider stricter checks.ui/app/src/components/DeleteContentTypeDialog/DeleteContentTypeDialogBody.tsx (1)
107-109
: Review: Usage ofkey
Attribute in Inline ElementThe added
key=""
attribute on the<Box>
component helps React’s reconciliation when elements are part of a dynamic list. However, using an empty string as a key is not ideal because:
- If this element isn’t part of an iterated list, the key attribute might be unnecessary.
- If it is part of a list, an empty key doesn’t provide a unique identifier which may lead to potential reconciliation issues.
Consider either removing the
key
attribute (if not needed) or assigning a meaningful, unique key.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
📒 Files selected for processing (99)
ui/app/package.json
(1 hunks)ui/app/src/CHANGELOG.md
(1 hunks)ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx
(1 hunks)ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx
(1 hunks)ui/app/src/components/ChangeContentTypeDialog/utils.ts
(1 hunks)ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/ContentTypeManagement.tsx
(4 hunks)ui/app/src/components/ContentTypeManagement/components/CreateTypeDialog.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/EditTypeView.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/EditTypeViewLayout.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/Layout.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/MainSection.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeBuilderAddButton.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeBuilderFormsEngine.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeCard.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeCardMedia.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeDetailsVIewHeader.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeList.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeListingView.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/archetypes.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/autoFileName.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/awsFileUpload.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/boxFileUpload.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/checkbox.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/colorPicker.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/dateTime.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/disabled.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/dropdown.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/fileName.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/forceHttps.ts
(2 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/imagePicker.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/input.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/internalName.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/label.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/linkInput.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/linkTextarea.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/linkedDropdown.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/localeSelector.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/nodeSelector.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/numericInput.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/pageNavOrder.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/repeat.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/rte.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/textarea.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/time.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/transcodedVideoPicker.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/uuid.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/controls/videoPicker.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/descriptors/dataSources/components.ts
(1 hunks)ui/app/src/components/ContentTypeManagement/utils.ts
(1 hunks)ui/app/src/components/DeleteContentTypeDialog/DeleteContentTypeDialogBody.tsx
(1 hunks)ui/app/src/components/FormsEngine/FormsEngine.tsx
(3 hunks)ui/app/src/components/FormsEngine/components/FormBackToTop.tsx
(1 hunks)ui/app/src/components/FormsEngine/components/FormLayout.tsx
(3 hunks)ui/app/src/components/FormsEngine/components/SectionAccordion.tsx
(1 hunks)ui/app/src/components/FormsEngine/components/TableOfContents.tsx
(3 hunks)ui/app/src/components/FormsEngine/controls/ColorPicker.tsx
(1 hunks)ui/app/src/components/FormsEngine/lib/controlHelpers.tsx
(1 hunks)ui/app/src/components/FormsEngine/lib/controlMap.ts
(3 hunks)ui/app/src/components/FormsEngine/lib/formConsts.ts
(2 hunks)ui/app/src/components/FormsEngine/lib/formUtils.tsx
(3 hunks)ui/app/src/components/FormsEngine/lib/formsEngineContext.ts
(3 hunks)ui/app/src/components/FormsEngine/lib/useSaveForm.tsx
(2 hunks)ui/app/src/components/FormsEngine/lib/validators.ts
(1 hunks)ui/app/src/components/FormsEngine/lib/valueRetrievers.ts
(2 hunks)ui/app/src/components/FormsEngine/lib/valueSerializers.ts
(2 hunks)ui/app/src/components/GlobalDialogManager/DialogStackItemContainer.tsx
(1 hunks)ui/app/src/components/ItemDisplay/ItemDisplay.tsx
(1 hunks)ui/app/src/components/LegacyComponentsPanel/utils.ts
(2 hunks)ui/app/src/components/NewContentDialog/NewContentCard.tsx
(0 hunks)ui/app/src/components/NewContentDialog/NewContentDialog.tsx
(2 hunks)ui/app/src/components/NewContentDialog/NewContentDialogContainer.tsx
(1 hunks)ui/app/src/components/NewContentDialog/index.ts
(0 hunks)ui/app/src/components/NewContentDialog/utils.ts
(1 hunks)ui/app/src/components/ResizeableDrawer/ResizeableDrawer.tsx
(1 hunks)ui/app/src/components/SearchBar/SearchBar.tsx
(5 hunks)ui/app/src/components/ViewToolbar/ViewToolbar.tsx
(2 hunks)ui/app/src/hooks/useFetchAllowedTypesForPath.tsx
(1 hunks)ui/app/src/hooks/useIsDarkModeTheme.tsx
(1 hunks)ui/app/src/hooks/useResizeObserver.ts
(1 hunks)ui/app/src/models/ContentType.ts
(8 hunks)ui/app/src/services/contentTypes.ts
(13 hunks)ui/app/src/state/reducers/dialogs/changeContentType.ts
(1 hunks)ui/app/src/state/reducers/dialogs/newContent.ts
(1 hunks)ui/app/src/utils/color.ts
(1 hunks)ui/app/src/utils/contentType.ts
(2 hunks)ui/app/src/utils/itemActions.ts
(1 hunks)ui/app/src/utils/object.ts
(2 hunks)ui/app/src/utils/path.ts
(1 hunks)ui/app/src/utils/string.ts
(1 hunks)ui/app/src/utils/system.ts
(3 hunks)ui/app/src/utils/ui.tsx
(2 hunks)
💤 Files with no reviewable changes (2)
- ui/app/src/components/NewContentDialog/NewContentCard.tsx
- ui/app/src/components/NewContentDialog/index.ts
🧰 Additional context used
🧬 Code Definitions (59)
ui/app/src/components/ContentTypeManagement/descriptors/controls/localeSelector.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/label.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/autoFileName.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/imagePicker.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkedDropdown.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/colorPicker.ts (1)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)
ui/app/src/components/ContentTypeManagement/descriptors/controls/repeat.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/awsFileUpload.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/dateTime.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkTextarea.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/input.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/videoPicker.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/nodeSelector.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkInput.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/time.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/textarea.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/checkbox.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/internalName.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/boxFileUpload.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/pageNavOrder.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/transcodedVideoPicker.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/dataSources/components.ts (1)
ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/dropdown.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/rte.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx (1)
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx (1) (1)
ChangeContentTypeDialogContainer
(31-73)
ui/app/src/components/LegacyComponentsPanel/utils.ts (1)
ui/app/src/utils/contentType.ts (1) (1)
createFormDefinitionPathFromTypeId
(207-209)
ui/app/src/components/ContentTypeManagement/descriptors/controls/uuid.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/utils/itemActions.ts (2)
ui/app/src/utils/system.ts (1) (1)
pickShowContentFormAction
(103-124)ui/app/src/components/NewContentDialog/utils.ts (1) (1)
NewContentDialogProps
(28-30)
ui/app/src/components/ContentTypeManagement/descriptors/controls/fileName.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/NewContentDialog/utils.ts (1)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)
ui/app/src/components/FormsEngine/FormsEngine.tsx (1)
ui/app/src/components/FormsEngine/components/FormBackToTop.tsx (1) (1)
FormBackToTop
(29-39)
ui/app/src/components/ContentTypeManagement/descriptors/controls/forceHttps.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/hooks/useFetchAllowedTypesForPath.tsx (2)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/services/contentTypes.ts (2) (2)
fetchLegacyContentTypes
(557-563)parseLegacyContentType
(499-517)
ui/app/src/components/ChangeContentTypeDialog/utils.ts (1)
ui/app/src/components/NewContentDialog/utils.ts (1) (1)
NewContentDialogProps
(28-30)
ui/app/src/components/ContentTypeManagement/components/TypeDetailsVIewHeader.tsx (2)
ui/app/src/models/ContentType.ts (1) (1)
PossibleContentTypeDraft
(183-185)ui/app/src/components/ContentTypeManagement/components/TypeCardMedia.tsx (1) (1)
TypeCardMedia
(30-67)
ui/app/src/components/FormsEngine/components/FormBackToTop.tsx (1)
ui/app/src/components/FormsEngine/lib/formUtils.tsx (1) (1)
getScrollContainer
(78-80)
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx (7)
ui/app/src/components/ChangeContentTypeDialog/utils.ts (1) (1)
ChangeContentTypeDialogContainerProps
(38-40)ui/app/src/components/ContentTypeManagement/components/TypeList.tsx (1) (1)
TypeListProps
(25-31)ui/app/src/utils/path.ts (1) (1)
withoutIndex
(84-86)ui/app/src/hooks/useFetchAllowedTypesForPath.tsx (1) (1)
useFetchAllowedTypesForPath
(26-57)ui/app/src/utils/contentType.ts (1) (1)
getNormalizedFolderPathForApi1GetTypes
(202-205)ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx (1) (1)
SelectTypeView
(40-76)ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (1) (1)
ObjectTypeOption
(25-25)
ui/app/src/components/ContentTypeManagement/components/TypeCardMedia.tsx (2)
ui/app/src/services/contentTypes.ts (1) (1)
fetchPreviewImage
(664-667)ui/app/src/utils/system.ts (1) (1)
consolidateSx
(99-101)
ui/app/src/components/FormsEngine/components/FormLayout.tsx (2)
ui/app/src/hooks/useResizeObserver.ts (1) (1)
useResizeObserver
(22-36)ui/app/src/utils/ui.tsx (1) (1)
getMarginSxProps
(49-54)
ui/app/src/components/ContentTypeManagement/descriptors/archetypes.ts (3)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/components/ContentTypeManagement/utils.ts (1) (1)
createEmptyTypeStructure
(202-221)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeManagement/components/TypeCard.tsx (3)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/components/ContentTypeManagement/components/TypeCardMedia.tsx (1) (1)
TypeCardMedia
(30-67)ui/app/src/utils/system.ts (1) (1)
consolidateSx
(99-101)
ui/app/src/components/ContentTypeManagement/descriptors/controls/numericInput.ts (2)
ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
PartialContentType
(200-200)createVirtualSection
(274-284)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)
ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (1)
ui/app/src/utils/object.ts (1) (1)
ref
(169-171)
ui/app/src/components/NewContentDialog/NewContentDialogContainer.tsx (7)
ui/app/src/components/NewContentDialog/utils.ts (1) (1)
NewContentDialogContainerProps
(38-40)ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/utils/path.ts (1) (1)
withoutIndex
(84-86)ui/app/src/components/ContentTypeManagement/components/TypeList.tsx (1) (1)
TypeListProps
(25-31)ui/app/src/hooks/useFetchAllowedTypesForPath.tsx (1) (1)
useFetchAllowedTypesForPath
(26-57)ui/app/src/utils/contentType.ts (1) (1)
getNormalizedFolderPathForApi1GetTypes
(202-205)ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx (1) (1)
SelectTypeView
(40-76)
ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx (4)
ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (3) (3)
ObjectTypeOption
(25-25)ContentTypesFilterProps
(23-23)ContentTypesFilter
(44-55)ui/app/src/components/SearchBar/SearchBar.tsx (2) (2)
SearchBarProps
(36-59)SearchBar
(61-204)ui/app/src/utils/system.ts (1) (1)
consolidateSx
(99-101)ui/app/src/utils/string.ts (1) (1)
isEmpty
(283-286)
ui/app/src/components/ContentTypeManagement/components/CreateTypeDialog.tsx (2)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/utils/string.ts (1) (1)
camelize
(25-29)
ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (26)
ui/app/src/models/ContentType.ts (1) (1)
ContentTypeField
(62-140)ui/app/src/utils/object.ts (1) (1)
foo
(282-282)ui/app/src/components/ContentTypeManagement/descriptors/controls/autoFileName.ts (1) (1)
autoFileNameDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/checkbox.ts (1) (1)
checkboxDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts (1) (1)
checkboxGroupDescriptor
(20-65)ui/app/src/components/ContentTypeManagement/descriptors/controls/dateTime.ts (1) (1)
dateTimeDescriptor
(20-75)ui/app/src/components/ContentTypeManagement/descriptors/controls/disabled.ts (1) (1)
disabledDescriptor
(17-23)ui/app/src/components/ContentTypeManagement/descriptors/controls/dropdown.ts (1) (1)
dropdownDescriptor
(20-58)ui/app/src/components/ContentTypeManagement/descriptors/controls/fileName.ts (1) (1)
fileNameDescriptor
(20-58)ui/app/src/components/ContentTypeManagement/descriptors/controls/forceHttps.ts (1) (1)
forceHttpsDescriptor
(20-34)ui/app/src/components/ContentTypeManagement/descriptors/controls/imagePicker.ts (1) (1)
imagePickerDescriptor
(20-68)ui/app/src/components/ContentTypeManagement/descriptors/controls/input.ts (1) (1)
inputDescriptor
(20-76)ui/app/src/components/ContentTypeManagement/descriptors/controls/label.ts (1) (1)
labelDescriptor
(20-34)ui/app/src/components/ContentTypeManagement/descriptors/controls/linkedDropdown.ts (1) (1)
linkedDropdownDescriptor
(20-51)ui/app/src/components/ContentTypeManagement/descriptors/controls/localeSelector.ts (1) (1)
localeSelectorDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/nodeSelector.ts (1) (1)
nodeSelectorDescriptor
(20-58)ui/app/src/components/ContentTypeManagement/descriptors/controls/numericInput.ts (1) (1)
numericInputDescriptor
(20-58)ui/app/src/components/ContentTypeManagement/descriptors/controls/pageNavOrder.ts (1) (1)
pageNavOrderDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/repeat.ts (1) (1)
repeatDescriptor
(20-58)ui/app/src/components/ContentTypeManagement/descriptors/controls/rte.ts (1) (1)
rteDescriptor
(20-65)ui/app/src/components/ContentTypeManagement/descriptors/controls/textarea.ts (1) (1)
textareaDescriptor
(20-72)ui/app/src/components/ContentTypeManagement/descriptors/controls/time.ts (1) (1)
timeDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/transcodedVideoPicker.ts (1) (1)
transcodedVideoPickerDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/uuid.ts (1) (1)
uuidDescriptor
(20-44)ui/app/src/components/ContentTypeManagement/descriptors/controls/videoPicker.ts (1) (1)
videoPickerDescriptor
(4-28)ui/app/src/components/ContentTypeManagement/descriptors/controls/colorPicker.ts (1) (1)
colorPickerDescriptor
(19-32)
ui/app/src/components/NewContentDialog/NewContentDialog.tsx (1)
ui/app/src/components/NewContentDialog/utils.ts (1) (1)
NewContentDialogProps
(28-30)
ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx (7)
ui/app/src/models/ContentType.ts (4) (4)
PossibleContentTypeDraft
(183-185)DataSource
(146-152)ContentTypeSection
(197-206)ContentType
(156-181)ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (2) (2)
FieldChipProps
(40-50)FieldChip
(52-149)ui/app/src/components/ContentTypeManagement/components/TypeDetailsVIewHeader.tsx (2) (2)
TypeDetailsHeaderProps
(31-34)TypeDetailsVIewHeader
(36-100)ui/app/src/components/FormsEngine/lib/formsEngineContext.ts (2) (2)
StableFormContextProps
(107-115)StableFormContext
(125-125)ui/app/src/components/ContentTypeManagement/utils.ts (3) (3)
createStableFormContextProps
(354-389)createVirtualSection
(274-284)createVirtualDataSourceFields
(286-298)ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (1) (1)
defaultDataSourcesSection
(98-102)ui/app/src/components/FormsEngine/components/SectionAccordion.tsx (1) (1)
SectionAccordion
(42-85)
ui/app/src/components/ViewToolbar/ViewToolbar.tsx (2)
ui/app/src/utils/object.ts (1) (1)
ref
(169-171)ui/app/src/utils/system.ts (1) (1)
consolidateSx
(99-101)
ui/app/src/components/FormsEngine/components/SectionAccordion.tsx (4)
ui/app/src/models/ContentType.ts (1) (1)
ContentTypeSection
(197-206)ui/app/src/hooks/useIsDarkModeTheme.tsx (1) (1)
isDarkModeTheme
(24-26)ui/app/src/components/FormsEngine/lib/formsEngineContext.ts (1) (1)
StableFormContext
(125-125)ui/app/src/utils/system.ts (1) (1)
consolidateSx
(99-101)
ui/app/src/components/FormsEngine/controls/ColorPicker.tsx (1)
ui/app/src/utils/color.ts (2) (2)
ColourFormat
(19-19)toTargetFormat
(21-36)
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (4)
ui/app/src/models/ContentType.ts (1) (1)
ContentTypeField
(62-140)ui/app/src/hooks/useIsDarkModeTheme.tsx (1) (1)
useIsDarkModeTheme
(20-22)ui/app/src/utils/string.ts (1) (1)
capitalize
(34-36)ui/app/src/components/ContentTypeManagement/components/TypeBuilderAddButton.tsx (1) (1)
TypeBuilderAddButton
(30-30)
ui/app/src/utils/contentType.ts (3)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (1) (1)
ObjectTypeOption
(25-25)ui/app/src/utils/string.ts (2) (2)
isEmpty
(283-286)ensureSingleSlash
(179-181)
ui/app/src/components/GlobalDialogManager/DialogStackItemContainer.tsx (1)
ui/app/src/utils/ui.tsx (1) (1)
displayWithPendingChangesConfirm
(25-47)
ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx (5)
ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (1) (1)
ObjectTypeOption
(25-25)ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx (2) (2)
TypeListControlBarProps
(30-44)TypeListControlBar
(48-107)ui/app/src/components/ContentTypeManagement/components/TypeList.tsx (2) (2)
TypeListProps
(25-31)TypeList
(33-70)ui/app/src/utils/contentType.ts (1) (1)
filterTypesByKeywordsAndObjectType
(187-200)
ui/app/src/components/FormsEngine/lib/formsEngineContext.ts (1)
ui/app/src/utils/system.ts (1) (1)
createUseContextHook
(132-145)
ui/app/src/components/FormsEngine/lib/valueSerializers.ts (1)
ui/app/src/models/ContentType.ts (1) (1)
ContentType
(156-181)
🪛 Biome (1.9.4)
ui/app/src/components/ContentTypeManagement/components/TypeCard.tsx
[error] 87-87: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
ui/app/src/components/ContentTypeManagement/components/CreateTypeDialog.tsx
[error] 139-139: A character class cannot match a character and a combining character.
A character and a combining character forms a new character. Replace the character class with an alternation.
(lint/suspicious/noMisleadingCharacterClass)
ui/app/src/components/ContentTypeManagement/components/TypeBuilderFormsEngine.tsx
[error] 169-169: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
ui/app/src/components/ContentTypeManagement/components/EditTypeView.tsx
[error] 393-393: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Travis CI - Pull Request
🔇 Additional comments (221)
ui/app/src/components/ContentTypeManagement/descriptors/controls/disabled.ts (2)
1-15
: License Header Verification:
The license header is well formatted and provides the complete GPL information as expected.
25-26
: Default Export Verification:
The default export ofdisabledDescriptor
is correctly implemented, facilitating its straightforward import in consuming modules.ui/app/src/components/ContentTypeManagement/components/TypeBuilderAddButton.tsx (4)
1-15
: License Header is Comprehensive and Compliant
The GPL license header is present and clear. No issues here.
17-17
: Proper Import of Material-UI Button
The import statement correctly pulls in the Button component from Material-UI.
30-30
: Explicit Component Export Strategy
Re-exporting Material-UI’s Button asTypeBuilderAddButton
is clear and acceptable given the current requirements. In the future, if customization is required, you might consider wrapping it with additional styling or behavior.
32-32
: Default Export is Consistent
The default export aligns with the named export, ensuring consistent usage across the project.ui/app/src/components/FormsEngine/components/TableOfContents.tsx (2)
124-127
: Good practice: Using section IDs instead of titles for keys and identifiersChanging from
section.title
tosection.id
for keys and identifiers is a good practice. IDs are typically more stable and unique than titles, which can change or contain characters that might cause issues when used as DOM identifiers.
115-115
:✅ Verification successful
Verify the purpose of
fooArray
in this contextChanging from an empty array
[]
tofooArray
for theselectedItems
prop may alter component behavior. Ensure this is intentional and thatfooArray
is properly defined for this use case.
🏁 Script executed:
#!/bin/bash # Search for the definition of fooArray to understand its purpose rg "export const fooArray" --type tsLength of output: 92
Subject: Confirmed Usage of
fooArray
forselectedItems
After verification, we've confirmed that
fooArray
is defined inui/app/src/utils/array.ts
as an empty array. This means usingfooArray
in place of an inline[]
does not change the initial value passed to the prop. However, please double-check that sharing the same empty array instance (instead of creating a new one on each render) aligns with the intended component behavior, especially if there's any risk of unintended mutations.ui/app/src/components/ContentTypeManagement/components/TypeBuilderFormsEngine.tsx (2)
83-89
: Avoid potential runtime error for nullcontainerRef
IfcontainerRef.current
is still null or undefined at the time of callingscroll()
, this may cause a runtime error. Consider adding a safety check:useEffect(() => { - containerRef.current.scroll({ top: 0, behavior: 'smooth' }); + containerRef.current?.scroll({ top: 0, behavior: 'smooth' }); }, [virtualType]);
255-265
: Remove or finalizeidentifyMode
if not used
The functionidentifyMode
is flagged with a TODO indicating possible removal. Confirm if it’s used elsewhere or can be safely removed to avoid confusion.ui/app/src/components/ContentTypeManagement/components/TypeCard.tsx (3)
36-39
: Well-defined style constants.The style constants are clearly defined and follow a good pattern for styling overrides in a React component.
43-63
: Good implementation of the TypeCard component structure.The component has a clean props structure with sensible defaults and proper destructuring.
64-83
: Well-designed card structure with flexible layout options.The card body implementation nicely handles both normal and skeleton states, with good use of the CardHeader component's slot props for styling flexibility.
ui/app/src/hooks/useIsDarkModeTheme.tsx (1)
17-29
: Well-structured utility for theme detection!This hook and utility function are cleanly implemented, providing an easy way to check if the current theme is in dark mode. The separation of concerns between the hook and the standalone utility function provides flexibility for both component and non-component contexts.
ui/app/src/utils/object.ts (1)
282-284
: Good use of Object.freeze for immutabilityUsing Object.freeze ensures these objects cannot be modified at runtime, which is a good practice for constants.
ui/app/src/hooks/useFetchAllowedTypesForPath.tsx (2)
26-30
: Consider adding a default return for empty paths.
Whenpath
is falsy, this hook does nothing and returns no content types. You may want to clarify whether this is indeed the desired behavior (i.e., returningundefined
forcontentTypes
) or if a fallback is needed for edge cases wherepath
is not provided.Would you like me to generate a quick test or script to verify that callers handle the undefined state properly?
32-52
: Good use of RxJS unsubscribe to prevent memory leaks.
Your subscription is properly disposed of on component unmount, safeguarding against potential memory leaks whenpath
changes rapidly.ui/app/src/components/SearchBar/SearchBar.tsx (2)
36-59
: Improved prop types for icons and input references.
Switching toElementType
for icons and introducing an optionalinputRef
helps with better typing and external refs integration. Good enhancement for reusability.
106-106
: Minor layout adjustments.
By settingminHeight
to 40px and adjusting padding, you provide a more compact UI. This is a subtle but welcome improvement for consistent spacing.Also applies to: 152-153
ui/app/src/components/ContentTypeFilter/ContentTypesFilter.tsx (2)
23-25
: Lightweight prop definitions promote reusability.
AdoptingSelectProps
as the base type, along withObjectTypeOption
, keeps this filter flexible. Ensure you’ve updated all call sites to provide validvalue
and handler properties.
44-55
: Ref forwarding and dynamic localization.
Wrapping theSelect
inforwardRef
provides a clean approach for parent components to access the DOM element, while the direct usage ofdefineMessages
fosters better internationalization.ui/app/src/components/FormsEngine/lib/formsEngineContext.ts (7)
17-17
: Imports look good.The imports are well organized with
createContext
from React andcreateUseContextHook
from the utility module.Also applies to: 27-27
117-117
: Pure function annotation for optimization.Adding the
/*#__PURE__*/
comment is a good practice as it helps bundlers like Webpack perform better tree-shaking by indicating this expression has no side effects.
120-121
: Pure function annotation for optimization.Good use of the pure function annotation for the global context creation.
125-125
: Pure function annotation for optimization.Consistent use of the pure function annotation for the form context creation.
128-128
: Pure function annotation for optimization.Good application of pure function annotation to ItemContext creation.
131-131
: Pure function annotation for optimization.Consistent application of pure function annotation to ItemMetaContext creation.
134-148
: Hook implementations look good.All context hooks are consistently implemented using the
createUseContextHook
utility with pure function annotations, which is a good practice for optimizing bundle size through more effective tree-shaking.ui/app/package.json (1)
101-101
:❓ Verification inconclusive
New color picker dependency added.
The addition of
react-colorful
is appropriate for adding color selection capabilities to the UI. This is a lightweight, accessible color picker library that integrates well with React applications.Ensure that this dependency is used consistently across the codebase where color picking functionality is needed.
🏁 Script executed:
#!/bin/bash # Check where react-colorful is imported rg "import.*react-colorful" --type ts --type tsxLength of output: 78
Below is a revised review comment. It clarifies that the dependency addition is correct, notes that its consistent usage must be verified, and recommends a new verification command using an explicit glob pattern to cover both TypeScript and TSX files.
Action Required: Please verify that the new
react-colorful
dependency is used consistently across the codebase.
- File: ui/app/package.json (line 101)
- Change: Addition of
"react-colorful": "^5.6.1"
, a lightweight, accessible color picker ideal for React.- Next Steps: Ensure that all modules requiring color picking integrate
react-colorful
. The initial verification command failed due to a file type recognition issue. Please re-run the following corrected search command to verify imports:Once you’ve confirmed consistent usage, kindly update the PR if necessary.
🏁 Script executed:
#!/bin/bash # Searching for react-colorful import statements in both ts and tsx files using an explicit glob pattern. rg "import.*react-colorful" --glob "*.{ts,tsx}"Length of output: 171
Action Required: Please manually verify that the added
react-colorful
dependency is utilized where color picking functionality is implemented.
- File: ui/app/package.json (line 101)
- Change: Addition of
"react-colorful": "^5.6.1"
- Next Steps:
The automated search using an explicit glob pattern did not yield any results. This may indicate that the dependency is not yet imported in any TypeScript or TSX files (or it is imported in a non-standard way). Please verify manually that:
- Color picker components are indeed using
react-colorful
.- There isn’t any dynamic or indirect import of
react-colorful
that might have been missed by the automated search.ui/app/src/components/ContentTypeManagement/descriptors/controls/colorPicker.ts (1)
17-32
: Clean implementation of color picker descriptorThis is a well-structured implementation of a color picker descriptor that follows the established pattern for control descriptors. The use of
createVirtualSection
for both properties and constraints sections is appropriate and consistent with other control descriptors.I note this is likely being added to support the new "react-colorful" dependency mentioned in the PR summary.
ui/app/src/utils/ui.tsx (2)
22-24
: Good addition of Material-UI type importsThese type imports from Material-UI are appropriate for the new utility function.
49-54
: Well-designed utility function for consistent spacingThe
getMarginSxProps
function is a good abstraction for common spacing patterns. This will help maintain consistent spacing throughout the application and reduce duplication of styling logic across components.The CSS selectors using
:not([hidden]) ~ :not([hidden])
pattern is the correct approach for applying spacing only between visible elements.ui/app/src/components/FormsEngine/lib/controlHelpers.tsx (1)
71-71
: Good defensive programming with optional chainingThis change adds optional chaining to safely access the
plugin
property, which prevents potential runtime errors iffield.properties
is undefined or null. This is a good defensive programming practice.ui/app/src/components/ContentTypeManagement/descriptors/controls/localeSelector.ts (1)
20-44
: Structure looks good for the locale selector descriptorThe descriptor is well-structured with clear sections for "Options" and "Constraints", providing a good foundation for the locale selector control within the Type Builder v2 framework.
ui/app/src/components/ContentTypeManagement/descriptors/controls/label.ts (1)
24-33
: Well-structured label descriptorThe label descriptor has a clear structure with appropriate fields for the text label control.
ui/app/src/components/ItemDisplay/ItemDisplay.tsx (2)
52-52
: Good enhancement to component flexibilityThe addition of the
component
prop and its use in the Box component makes the ItemDisplay more flexible, allowing consumers to specify what HTML element should be rendered. This is a good improvement that follows component composition best practices.Also applies to: 86-86
73-73
: Nice default value for component propSetting the default value to 'span' maintains backward compatibility with existing code that relies on the previous hardcoded behavior.
ui/app/src/components/ContentTypeManagement/descriptors/controls/time.ts (1)
46-47
: Code structure looks goodThe dual export pattern (named and default) provides flexibility for different import styles.
ui/app/src/components/ContentTypeManagement/descriptors/controls/linkInput.ts (1)
20-44
: Good use of explicit typing with PartialContentTypeThe explicit typing of
linkInputDescriptor
asPartialContentType
improves type safety and helps with development tools support.ui/app/src/components/ContentTypeManagement/descriptors/controls/videoPicker.ts (1)
4-28
: Good use of explicit typing with PartialContentTypeThe explicit typing of
videoPickerDescriptor
asPartialContentType
improves type safety and helps with development tools support.ui/app/src/components/FormsEngine/lib/formConsts.ts (1)
37-38
: XML keys added for enhanced content type functionality.The addition of
disabled
andplaceInNav
to the XmlKeys enum provides necessary support for new content type management features. This aligns well with the Type Builder v2 refactoring effort.ui/app/src/components/ContentTypeManagement/descriptors/controls/linkedDropdown.ts (1)
20-27
: LGTM! Well-structured descriptor with logical section organization.The linkedDropdown descriptor is clearly organized with appropriate sections for "Options" and "Constraints". This follows the pattern established in other descriptors and provides a consistent user experience.
ui/app/src/components/ContentTypeManagement/descriptors/controls/numericInput.ts (1)
24-27
: Well-organized sections with logical field grouping.The descriptor has a clear separation between "Options" and "Constraints" sections, making the UI more intuitive for users.
ui/app/src/components/ContentTypeManagement/descriptors/controls/input.ts (1)
25-31
: Good use of explicit section IDs.Unlike other descriptors, this one explicitly defines section IDs (
properties
andconstraints
), which is good for referencing specific sections. Consider applying this pattern to other descriptors for consistency.ui/app/src/components/ContentTypeManagement/descriptors/controls/dateTime.ts (1)
1-78
: Well-structured content type descriptor for date-time control.This file creates a well-organized descriptor for the date and time picker component. The structure follows a clean pattern with sections for "Options" and "Constraints" that organize the fields logically. The fields properly define all necessary properties, making this descriptor ready for integration with the Type Builder framework.
One minor note: Consider whether the
foo
validation object (imported from utils/object.ts) could be renamed to something more descriptive of its purpose, especially as this pattern is being repeated across multiple descriptors.ui/app/src/components/ContentTypeManagement/descriptors/controls/nodeSelector.ts (1)
1-61
: Well-structured content type descriptor for node selector.The node selector descriptor is well-defined with appropriate sections and fields. The use of
createVirtualSection
keeps the code DRY and consistent with other descriptors. The type annotation ensures type safety within the Type Builder framework.ui/app/src/components/ContentTypeManagement/descriptors/controls/pageNavOrder.ts (1)
1-47
: Well-structured content type descriptor for page navigation ordering.This descriptor follows the same pattern as the others, maintaining consistency across the control descriptors. The "Options" and "Constraints" sections are appropriately organized, and all fields have the necessary properties.
ui/app/src/components/ContentTypeManagement/descriptors/controls/internalName.ts (1)
21-21
:❓ Verification inconclusive
Address the TODO comment.
There's a TODO questioning why internal name is a control type. This should be resolved before finalizing the code to ensure all included components are necessary.
🏁 Script executed:
#!/bin/bash # Description: Search for usage of internalName as a control type # Look for references to internalName in the codebase echo "Searching for references to XmlKeys.internalName or internal-name-control..." rg -i "internalName|internal-name" --type ts --type tsxLength of output: 248
Below is an updated review comment based on the verification attempt. It highlights that an improved search is now needed—specifically using file globbing—to conclusively determine if the control type is used. Please run the updated search command manually and verify the findings before proceeding with removal or any further refactoring.
Action Required: Verify and Resolve Unused Internal Name Control
There is a TODO in
ui/app/src/components/ContentTypeManagement/descriptors/controls/internalName.ts
(line 21) questioning why “internal name” is treated as a control type. The initial verification command encountered a file type error with.tsx
files, so its output wasn’t conclusive.
- Next Steps:
- Manually re-run a revised search using the updated command:
rg -i 'internalName|internal-name' -g '*.ts' -g '*.tsx'- Confirm whether the internal name control is ever referenced in the codebase.
- If no usage is found, remove or refactor as appropriate. If it’s actually needed, remove the TODO comment and add documentation explaining its purpose.
ui/app/src/utils/itemActions.ts (2)
608-608
: Type assertion change improves flexibility.Changing from
NewContentDialogProps
toPartial<NewContentDialogProps>
allows for more flexibility in what props can be passed to the component, which is beneficial for this refactoring effort.
597-607
:❓ Verification inconclusive
API refactoring improves clarity but verify compatibility.
The refactoring of parameters passed to
pickShowContentFormAction
improves clarity by using explicit parameters (contentTypeId
,isNewContent
) rather than relying onrootPath
. This aligns well with the Type Builder v2 changes mentioned in PR objectives.Verify that all callers to this function are updated to handle the new parameter structure:
🏁 Script executed:
#!/bin/bash # Description: Find all usages of pickShowContentFormAction to verify they're updated echo "Searching for other uses of pickShowContentFormAction that might need updating..." rg "pickShowContentFormAction" --type ts --type tsx -A 5 -B 5Length of output: 262
Action: Verify that all callers of
pickShowContentFormAction
are updated properlyThe initial search command returned an error due to the unrecognized file type "tsx." To address this, please re-run the search using an updated script with glob patterns to include both
.ts
and.tsx
files. For example:#!/bin/bash echo "Searching for all usages of pickShowContentFormAction in TypeScript files..." echo "Searching in .ts files:" rg "pickShowContentFormAction" -g "*.ts" -A 5 -B 5 echo "Searching in .tsx files:" rg "pickShowContentFormAction" -g "*.tsx" -A 5 -B 5Once executed, verify that every caller of
pickShowContentFormAction
is adjusted to handle the new parameter structure (using explicit parameters likecontentTypeId
andisNewContent
) as per the API refactoring and Type Builder v2 changes.ui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts (2)
18-18
:❓ Verification inconclusive
Review the placeholder validation object.
The code imports
foo
from utils/object.ts which is just an empty frozen object. This appears to be a placeholder.
🏁 Script executed:
#!/bin/bash # Check if other files are using similar pattern or if this might be intended to be replaced rg --type ts "validations: foo" -A 1 -B 1Length of output: 35983
Placeholder Validation Consistency
The import of
foo
from'../../../../utils/object'
inui/app/src/components/ContentTypeManagement/descriptors/controls/checkboxGroup.ts
(line 18) is used as the validation object. Our search shows that this pattern (i.e., using a frozen, empty object as a stand-in for validations) is widespread across many descriptor controls.
- Confirm whether the use of
foo
as a placeholder is intentional.- If a proper validation mechanism should be implemented later, please add a TODO or inline comment to indicate its temporary nature and plan for updating it.
24-26
:⚠️ Potential issueMissing implementation for tokenize field.
The section
Options
includestokenize
in its fields array, but there's no corresponding field implementation in thefields
object.You should either:
- Remove 'tokenize' from the fields array in the Options section, or
- Add the tokenize field implementation to the fields object:
- createVirtualSection({ title: 'Options', fields: ['options', 'readonly'] }), + createVirtualSection({ title: 'Options', fields: ['options', 'readonly'] }),Likely an incorrect or invalid review comment.
ui/app/src/components/FormsEngine/components/FormBackToTop.tsx (1)
24-39
: Well-implemented component with good structure.The
FormBackToTop
component is well-structured with clear props interface and proper implementation. It uses Material-UI components effectively and provides smooth scrolling functionality.ui/app/src/utils/string.ts (2)
283-286
: Well implemented string validation utility.This function properly checks if a string is null or contains only whitespace, which is a common validation need throughout the application. The implementation correctly handles the null case first and then uses trim() to check for empty strings.
288-290
: Good addition of type-safe boolean to string conversion.The function correctly converts boolean values to their string representation with appropriate TypeScript return type union ('true' | 'false'). This will help prevent type errors when string representations of booleans are needed.
ui/app/src/state/reducers/dialogs/changeContentType.ts (1)
25-32
: State simplification looks good.The removal of
compact
,rootPath
, andselectedContentType
properties in favor of a singleinitialCompact
property simplifies the state model. This aligns with the broader refactoring efforts mentioned in the PR objectives to enhance reusability within the Type Builder 2 framework.ui/app/src/components/ContentTypeManagement/components/MainSection.tsx (1)
22-51
: Well-implemented responsive layout component.The
Main
component is well designed with:
- Proper TypeScript interface for props
- Correct implementation of
shouldForwardProp
to filter non-DOM props- Clean transition effects that change based on the drawer state
- Proper theme integration following Material-UI conventions
This will provide a smooth user experience when interacting with the drawer interface.
ui/app/src/components/LegacyComponentsPanel/utils.ts (1)
24-24
: Good refactoring for path generation.Replacing the hardcoded path with
createFormDefinitionPathFromTypeId
centralizes the logic for content type path construction. This improves maintainability by ensuring path formats are consistent across the application and only need to be updated in one place if the format changes.Also applies to: 132-132
ui/app/src/components/FormsEngine/lib/useSaveForm.tsx (1)
166-166
: Export changed from named to default.The function is now exported as a default export rather than a named export, which changes how it must be imported in other files.
This change simplifies imports in other modules and aligns with common React patterns. I verified that the import was also updated in FormsEngine.tsx accordingly.
ui/app/src/state/reducers/dialogs/newContent.ts (1)
26-27
: Props structure simplified.The initial state has been refactored to use
initialCompact
instead ofcompact
, androotPath
has been removed entirely.This change aligns with the broader refactoring across dialog components and simplifies the state structure by removing unnecessary properties.
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx (3)
24-24
: Props destructuring updated.The destructuring pattern has been updated to use
initialCompact
instead ofcompact
,rootPath
, andselectedContentType
.This simplification aligns with the changes made to the initial state in
newContent.ts
and creates a more consistent API across the application.
27-31
: Dialog appearance updated.The dialog has been enhanced with a
maxWidth
property and updated title and subtitle text that better describes its purpose.The new text clarifies that this dialog is specifically for changing an existing content type rather than choosing a new one, providing better context to users.
36-36
: Prop name updated for container component.The prop passed to
ChangeContentTypeDialogContainer
has been updated fromcompact
toinitialCompact
.This change ensures consistency with the updated props structure and maintains proper data flow between components.
ui/app/src/components/FormsEngine/FormsEngine.tsx (2)
113-113
: Import updated to use default import.The import of
useSaveForm
has been changed from a named import to a default import.This change corresponds to the updated export in
useSaveForm.tsx
, maintaining consistency across the codebase.
833-833
: Back-to-top functionality refactored into a dedicated component.The inline implementation using Box, Tooltip, and Fab has been replaced with the more concise
FormBackToTop
component.This refactoring improves code maintainability by extracting reusable UI functionality into a dedicated component. The
FormBackToTop
component maintains the same functionality while simplifying the JSX structure.ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (3)
33-34
: Good addition of textOrNullExtractor for better null handlingThis function properly returns null when the value is falsy instead of an empty string, providing better type safety for components that need to distinguish between empty strings and null values.
35-36
: Improved type handling for numeric inputsThe addition of
numberFieldExtractor
is a good improvement that ensures numeric values are properly typed as numbers rather than strings, and correctly handles null values.
60-61
: Good replacement of text extractor with number extractor for numeric inputsReplacing
textFieldExtractor
withnumberFieldExtractor
for 'numeric-input' makes more sense semantically and improves type safety. The addition ofcolorPicker
withtextOrNullExtractor
suggests integration with the newly added 'react-colorful' dependency mentioned in the PR.Also applies to: 67-69
ui/app/src/components/NewContentDialog/NewContentDialog.tsx (2)
24-25
: Good simplification of propsReplacing
rootPath
andcompact
withinitialCompact
simplifies the component's API. This change aligns with the PR objective of refactoring to improve reusability.Also applies to: 41-42
26-36
: Improved dialog structureMoving the title into
dialogHeaderProps
and adding themaxWidth="lg"
property makes the dialog more consistent with the new development standards mentioned in the PR objectives.ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx (1)
55-59
: Good implementation of search filteringThe filtering logic properly handles case-insensitive searches across both the name and description fields, providing a user-friendly search experience.
ui/app/src/components/FormsEngine/components/FormLayout.tsx (3)
38-39
: Good addition of utility hook and function imports.The import of
getMarginSxProps
anduseResizeObserver
will help simplify the component code by abstracting reusable functionality.
127-135
: Cleaner implementation with the useResizeObserver hook.The resize observer implementation has been refactored to use a custom hook, which significantly improves the code by:
- Eliminating manual subscription management
- Reducing boilerplate code
- Improving cleanup handling
This change follows the React hooks pattern and makes the component more maintainable.
149-149
: Good use of utility function for styling.Replacing inline styling with the
getMarginSxProps()
utility function improves code maintainability and consistency across the application.ui/app/src/components/NewContentDialog/utils.ts (3)
17-17
: Appropriate update to ContentType import.Importing the standard
ContentType
interface aligns with the modernization efforts mentioned in the PR description.
25-25
: Improved property naming with initialCompact.Changing from
compact
toinitialCompact
better indicates this is an initial state value that the component can internally manage, following React's controlled component pattern.
29-29
: Simplified callback signature.The
onContentTypeSelected
signature has been greatly simplified to include only the essential information (path and contentType), reducing coupling between components and making the interface more maintainable.ui/app/src/components/ContentTypeManagement/components/SelectTypeView.tsx (2)
28-38
: Well-structured component interface.The
SelectContentTypeProps
interface is clearly defined with:
- Optional styling
- Configurable initial states
- Required content type list
- Flexible slot props for customization
This provides a good balance between required functionality and customization options.
63-74
: Good use of slot props pattern for component customization.The component uses the slot props pattern effectively, allowing for customization of inner components while maintaining control over their props. This is particularly valuable for a reusable component like this one.
ui/app/src/utils/system.ts (2)
109-110
: Enhanced dialog configuration options.Adding
allowFullScreen
andallowMinimize
properties improves the user experience by providing more control over dialog behavior.
126-145
: Excellent utility for context hook creation.The
createUseContextHook
utility function:
- Provides type-safe context consumption
- Offers better error messages when contexts are accessed outside their providers
- Allows for property selection through an optional selector function
- Creates a consistent pattern for context hooks across the application
This is a well-designed utility that will improve code quality and developer experience.
ui/app/src/components/ContentTypeManagement/components/TypeListingView.tsx (2)
41-49
: TODO comment needs to be addressedThere's a TODO comment on line 45 about adding config-based archetypes. Make sure to track this as a future enhancement.
Also, the undefined default value on line 46 could be made more explicit by using a proper defaulting mechanism rather than passing undefined directly.
65-92
: LGTM! The component layout and structure are well-organizedThe component renders a well-structured UI with proper conditional rendering and prop passing. The organization of the toolbar, content area, and dialog is clean and follows best practices.
ui/app/src/components/ChangeContentTypeDialog/utils.ts (3)
21-21
: LGTM! Good improvement in maintaining consistent importsAdding the import for
NewContentDialogProps
allows for better type consistency across related dialog components.
23-26
: Improved property management with initialCompactThe removal of multiple properties (
rootPath
,compact
,selectedContentType
) in favor of a singleinitialCompact
property simplifies the interface and makes it more maintainable.
28-30
: Enhanced type safety for callback functionUsing
NewContentDialogProps['onContentTypeSelected']
for typing theonContentTypeSelected
property ensures consistency across dialog components and provides better type safety than the previousany
type.ui/app/src/components/FormsEngine/lib/valueSerializers.ts (2)
135-147
: Good refactoring of XML builder creation logicExtracting the XML builder creation into a separate function improves code modularity and reusability. The TODO comment about moving this to a utils file is appropriate, as this is a utility function that could be used elsewhere.
However, ensure you create a follow-up task to move this function to the utils file as suggested in the TODO comment.
149-157
: Function refactoring improves code readabilityThe updated
buildContentXml
function now uses the extractedgetXmlBuilder
function, which improves readability and maintainability. This is a good example of the Single Responsibility Principle.Follow up on the TODO comment to move this function to content.ts as part of ongoing refactoring efforts.
ui/app/src/components/ContentTypeManagement/components/Layout.tsx (3)
40-66
: Well-structured component with good use of React patterns.The component makes effective use of
forwardRef
anduseImperativeHandle
to expose the container reference to parent components. The resize observer implementation provides responsive behavior based on container dimensions.
50-63
: Good implementation of responsive layout logic.The resize observer logic handles viewport resizing well, dynamically adjusting the drawer visibility and width based on available space. The CSS variable approach for dimensions is a clean solution for reactive layouts.
88-137
: Clean conditional rendering between Drawer and Dialog.The component intelligently switches between Drawer and Dialog components based on available screen space, providing a good user experience across different viewport sizes.
ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx (1)
88-91
: Improve type safety of ContentTypesFilter props.The TypeScript cast
(slotProps?.contentTypesFilter as Omit<SelectProps, 'variant' | 'ref'>)
might be risky. Consider using a more type-safe approach or add runtime validation.Consider using a TypeScript utility type or adding a runtime check to ensure the props match the expected shape.
ui/app/src/components/GlobalDialogManager/DialogStackItemContainer.tsx (1)
20-121
: Well-structured refactoring improves maintainabilityThe refactoring changes in this file significantly improve code organization by separating concerns into distinct functions:
- The main
DialogStackItemContainer
component is now simplifiedpickDialogComponent
handles component selection logiccreateUnknownComponent
handles unknown component renderinguseCreateCallbackProps
encapsulates callback creation and state managementThis separation of concerns makes the code more maintainable and testable.
ui/app/src/utils/contentType.ts (3)
187-200
: Good addition for content type filteringThe
filterTypesByKeywordsAndObjectType
function provides a clean implementation for filtering content types based on keywords and object types. It includes proper null checks and early returns for edge cases.
202-205
: Workaround for API inconsistency with proper documentationThe function correctly handles the folder path normalization required by the API, and the TODO reference to the GitHub issue provides context for why this workaround is necessary.
207-209
: Clean path construction with proper handlingThe
createFormDefinitionPathFromTypeId
function usesensureSingleSlash
to properly handle path construction, preventing potential issues with duplicate slashes in paths.ui/app/src/components/FormsEngine/lib/controlMap.ts (2)
23-51
: Improved organization of control types with clear TODOsThe control types have been reordered and labeled with helpful TODO comments indicating which ones:
- Are planned for removal
- Are not in use
- Are not part of business processes
This kind of documentation helps future developers understand the codebase status.
53-83
:✅ Verification successful
New and restored control types improve feature set
The changes restore the
checkbox-group
control, add support forrepeat
control, and introduce a newcolorPicker
control. These additions enhance the forms engine capabilities.Make sure the new
ColorPicker
component is properly implemented and tested, as it's a newly added feature.
🏁 Script executed:
#!/bin/bash # Check if the ColorPicker component exists and is properly implemented fd "ColorPicker.tsx" --type f --exec cat {} \;Length of output: 5102
Controls Enhancement Verified
• The restored
checkbox-group
and newly addedrepeat
controls are properly mapped in the control map.
• The newcolorPicker
control correctly lazy-loads theColorPicker
component, which has been verified to exist and is fully implemented in the repository.Please ensure that comprehensive tests are in place to validate the behavior of the new
ColorPicker
feature.ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx (2)
18-29
: No issues with newly introduced imports.These imports (React,
SelectTypeView
, path utilities, etc.) appear to be well-structured and meet the component’s requirements. Everything seems consistent; no redundant imports identified.
38-41
: Confirm thatitem.systemType
is valid.When filtering the list of types, you rely on
type.type === item.systemType
. Ifitem.systemType
can be invalid or empty, some content types may inadvertently be excluded. You may wish to verify the correctness ofitem.systemType
or fall back to a default value to avoid missing content types.ui/app/src/components/FormsEngine/lib/formUtils.tsx (3)
88-88
: Ensure uniquesection.id
values.Switching from indexing by
section.title
tosection.id
in the expanded-state atoms is more robust—titles can change, whereas IDs ideally remain stable. Just confirm that eachsection.id
is guaranteed to be unique to avoid accidental collisions in the generated atom map.
251-257
: Helpful improvement in alert usage.The
useShowAlert
hook’s ability to accept either a string or object minusdispatch
nicely streamlines alert invocation. It makes the API friendlier since callers no longer need direct access todispatch
. This approach looks clean and safe for typical usage scenarios.
442-447
: Check for consistency with boolean-based keys.The newly added
disabled
andplaceInNav
boolean fields are consistent with the preceding properties that store booleans. Just ensure that downstream consumers expect boolean types instead of string equivalents (e.g.,'false'
,'true'
). Everything else looks good.ui/app/src/components/ViewToolbar/ViewToolbar.tsx (5)
18-19
: Clean import consolidation.Importing
ToolbarProps
andconsolidateSx
fosters clarity. This makes it more explicit which Material-UI props are extended and helps unify styling logic withconsolidateSx
.Also applies to: 23-23
27-27
: Enhanced flexibility withslotProps
.Exposing
slotProps
gives callers more granular control of the underlyingToolbar
. This pattern improves extensibility without bloating the main component’s props.Also applies to: 31-32
34-35
: Smooth transition toforwardRef
.Using
forwardRef
onViewToolbar
is a solid refinement. It allows parent components to capture a reference to the underlying DOM element. This is especially helpful in advanced layouts or scroll handling.Also applies to: 38-38
51-51
: Seamlessly merging styles withconsolidateSx
.Spreading in
slotProps?.toolbar
and merging styles viaconsolidateSx
effectively extends the default Toolbar without losing existing styles. This approach is succinct and consistent with MUI best practices.Also applies to: 53-66
73-73
: Ref and memo synergy.Wrapping the
ViewToolbar
inReact.memo
and re-exporting it asMemo
is a clean way to optimize re-renders. This pattern remains flexible while preventing needless re-renders when props don’t change.Also applies to: 75-75, 77-77
ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx (1)
61-75
: Consider null/undefined checks for thetype
prop.The
TypeDetailsView
component relies ontype
and its nested properties (type.sections
,type.dataSources
, etc.) without an explicit check for null or undefined. Iftype
is not guaranteed to be defined at all times, you may want to add robust null/undefined checks to avoid potential runtime errors.ui/app/src/components/ContentTypeManagement/ContentTypeManagement.tsx (2)
84-110
: Confirm the correctness of the alert severity messages.The alert switches between
'warning'
and'info'
based on theuseLegacy
flag. Double-check that the user flow is correct: it may be helpful to provide consistent messaging or styling to communicate the difference between the new tool and legacy tool more distinctly.
139-181
: Ensure stable unsubscribing from the event stream.The
messagesSubscription.unsubscribe()
call in the cleanup function is correct, but confirm that no other subscriptions are left open, especially if you expect multiple messages or expansions of this system in the future. This helps avoid memory leaks and keeps your code scalable.ui/app/src/components/FormsEngine/components/SectionAccordion.tsx (15)
18-18
: Import looks good.
No issues identified with this new import statement.
20-20
: Import looks good.
No issues identified with this new import.
21-21
: Import looks good.
No issues identified with this new type import.
28-28
: Library import check.
UsingconsolidateSx
to merge style props is an effective approach for MUI style consolidation.
29-29
: Dark mode detection check.
TheisDarkModeTheme
hook integrates well with MUI theme logic. No issues found.
31-33
: Interface extension.
The addition ofchildren
andcolorize
flags toSectionAccordionProps
is clear and consistent.
36-39
: Optional slot props.
Allowing partial overrides for summary and details is a good approach to enhance extensibility.
42-49
: Function signature update.
Destructuring multiple custom props while extendingAccordionProps
is aligned with MUI patterns and keeps the component flexible.
51-52
: Dark mode usage.
No concerns regarding the logic for retrieving the dark mode value and expanded state from context.
55-56
: Elevation props usage.
Conditionally applyingelevation
based on dark mode is a sensible UI approach.
59-72
: Dynamic styling with consolidateSx.
Conditionally applying border styles for colorized sections is appropriate. Ensure that design guidelines permit a 5px left border for highlight.
74-74
: AccordionSummary props extension.
Passing downslotProps?.accordionSummary
is well aligned with MUI’s new slotProps approach.
76-76
: Slot-prop children usage.
Child elements in the summary are appended correctly, providing flexibility for customizing the summary content.
78-81
: AccordionDetails usage.
Rendering fields and optional extra children within details is clear. This structure cleanly supports dynamic content.
82-82
: Children after AccordionDetails.
Placingchildren
afterAccordionDetails
can be intentional for custom layouts. No issues found.ui/app/src/CHANGELOG.md (6)
32-32
: Changelog entry for dialog prop changes.
Accurately documents the removal ofrootPath
,compact
, andselectedContentType
fromChangeContentTypeDialog
plus addition ofinitialCompact
. Good clarity.
33-33
: ContentTypesFilter changes.
Notes that it’s “completely redone” to align with@mui/material/SelectProps
. Adequate documentation for a breaking change.
34-34
: Removal of NewContentCard.
Straightforward, no concerns.
35-35
: Removal of ContentTypesGrid.
Change is clearly documented. No issues.
36-36
: Removal of ContentTypesLoader.
Clear comment on removal. No concerns.
37-38
: NewContentDialog changes.
Reflects removed props and introducesinitialCompact
, with revised signature foronContentTypeSelected
. Documented thoroughly.ui/app/src/utils/color.ts (8)
1-15
: License header and file creation.
No issues with the license text or basic file setup.
17-17
: MUI system imports.
LoadingdecomposeColor
,hslToRgb
,recomposeColor
, andrgbToHex
from@mui/system
is correct for color transformations.
19-19
: ColourFormat type.
Defining'rgb' | 'hsl' | 'hex'
is a straightforward and well-scoped union.
21-36
: toTargetFormat function.
Routing color format conversions through the specialized helpers is clean. The fallback logic with switch-case is well structured.
38-51
: anyColorToHex function.
Decomposes color, optionally strips alpha channels, and usesrgbToHex
. Implementation is clear.
53-64
: anyColorToRgb function.
Methodically handles whether alpha is included. Potentially robust for different color inputs.
66-90
: anyColorToHsl function.
Nicely re-maps color to HSL format. The approach to remove alpha ifallowAlpha
is false is consistent with the others.
92-120
: rgbValuesToHslValues function.
Computes HSL from RGB with a standard formula. Rounding results to integers is typical for display usage.ui/app/src/components/NewContentDialog/NewContentDialogContainer.tsx (9)
18-20
: Internationalization and React.
Pulling inFormattedMessage
andReact
in separate lines is fine. No issues.
23-23
: TypeListProps import.
Needed for referencing theonCardClick
type. Straightforward.
25-25
: SelectTypeView import.
No conflicts with naming, adheres to new structure.
27-29
: Components & hook import.
ItemDisplay
,Box
, anduseFetchAllowedTypesForPath
are properly used. No concerns.
32-32
: ReceivinginitialCompact
.
Respects the newly added property. Proper destructuring with fallback is good.
34-36
: handleContentTypeSelected callback.
Correctly callsonContentTypeSelected
with the simplified object containingpath
andcontentType
.
38-38
: TypeListonCardClick
binding.
Maps card clicks to the samehandleContentTypeSelected
. Straightforward.
40-40
: useFetchAllowedTypesForPath usage.
Leverages normalized path. Good practice for consistent folder path retrieval.
43-65
: Dialog structure.
UtilizesSelectTypeView
with skeleton states and left children showing the target item. The approach is user-friendly and minimal.ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (2)
1-15
: Header & Licensing Check
The GPL license header is correctly placed. No issues found with licensing references.
148-178
: Control descriptors registry review
The centralizedcontrolDescriptors
record is well-structured and supports multiple built-in control definitions. This approach promotes modularity and improves maintainability. No concerns identified.ui/app/src/models/ContentType.ts (9)
18-18
: New import reference
ImportingXmlKeys
to handle references in forms. This is coherent with the forms engine integration. Looks good.
159-160
: Addeddescription
property
Attaching a requireddescription
string to theContentType
is clear. Confirm if empty or optional description is disallowed.Do we ever store or display an empty string when no user description is provided? If so, consider making this field optional.
164-164
: NewmergeStrategy
property
This property extends type configurability. Looks consistent with the PR objective to enhance content type metadata.
183-185
:PossibleContentTypeDraft
interface
Allowing aNEW
flag is useful for distinguishing unsaved types from the existing ones. Implementation looks solid and helps manage creation flows.
187-195
:ContentTypeBasicDetails
interface
Storing basic content type attributes (controller, imageThumbnail, no-template-required, paths) in one interface is convenient. Good job.
198-206
:ContentTypeSection
additions
Addingid
andcolor
for sections is a user-friendly approach for theming or dark-mode styling. No issues.
250-252
: Sections with IDs
The comment clarifies that sections in legacy definitions now require IDs. This helps keep track of them in the new builder.
262-303
:SerializeToXmlContentTypeStructure
interface
Defines how the content type is serialized to XML. The additions such asdescription
,merge-strategy
, andpaths
match the new content type properties in the system.
335-335
: Clarification onform
The comment clarifying(legacyType.form === legacyType.name)
is helpful. The code is consistent with legacy references.ui/app/src/components/ContentTypeManagement/components/EditTypeView.tsx (13)
1-16
: File-level overview
A new React component file for editing content types. The licensing header is provided, with no issues.
69-78
: Props forEditTypeAppProps
Well-defined interface that includes a user-providedtype
and callbacks. Clear structure to customize behaviors likeonClose
.
94-108
:EditAppContextProps
interface
Tracks form updates, form context, and the selected artefact. This is a neat approach ensuring each form has consistent event streams.
109-401
: CoreEditTypeView
implementation
Overall logic is well-organized, covering the approach of opening/closing forms, merging updates, saving to the server, and using the forms engine. No immediate correctness/security issues, except for the highlight usage below.🧰 Tools
🪛 Biome (1.9.4)
[error] 393-393: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
403-413
:createContextObject()
Initializes app context for field updates and selected artefacts. Straightforward with no concerns.
415-419
:getIdFromIdPath
Simple utility that extracts the last portion of a dot-separated path. This is concise and effective.
420-430
:insertSection
Inserts a new section at a specified index. The logic is straightforward, no issues found.
426-431
:addField
Merges the new field intofields
while leavingsections
unchanged. Implementation is correct for the current approach.
432-434
:updateTypeProps()
Merges partial updated type details into the existing type. Relies onpluckProps
to ensure only valid properties get updated. No concerns.
436-465
:updateTypeFromFieldUpdate()
Merges updated field values back into the type, handles an ID change by updating the sections array as well. This ensures references remain consistent.
479-489
:updateTypeFromDataSourceUpdate()
Generates a shallow copy ofdataSources
and updates the target. Implementation is consistent with the approach used for fields and sections.
491-503
:save()
Serializes the content type to XML, with an option to do a real server write. This modular approach is easy to maintain. Good job.
505-508
:validityAtomsHaveErrors()
Checks for any form field validations that are invalid. Clear logic, no concerns.ui/app/src/services/contentTypes.ts (23)
23-24
: Imports look good.
These newly added imports,ContentTypeSection
andDataSource
, are properly referenced in the file.
33-33
: New utility imports.
The added importcamelize, capitalize, isBlank, toColor
from../utils/string
is consistent with the usage below.
343-343
: Local variable usage.
DefiningpropertyProp
simplifies multiple references tolegacyField.properties?.property
.
345-369
: Repeat field validations.
The logic to set min/max counts and mark the field as required ifmin > 0
is clear and correct.
373-374
: Spread usage for validations.
Merging validations withgetFieldValidations(propertyProp, dropTargetsLookup)
keeps the node-selector case concise.
387-388
: Combining validations.
Spreading both generic validations and data-source-specific validations is a neat approach for input/textarea fields.
395-395
: Video-picker/rte validations.
Again spreading data-source-specific validations keeps the logic consistent for these field types.
409-410
: New arrays and lookups.
sections
anddataSources
are now strongly typed. This improves clarity and maintainability.
413-414
: Conversion to array.
Convertingdefinition.datasources?.datasource
to an array ensures uniform iteration.
416-418
: Building the local dataSources lookup.
Copying fields from the legacy data source while reinitializingproperties
is logical for further customization.
420-434
: Defaulting invalid numeric properties to 0.
Whenvalue
is NaN, it's set to 0. Confirm whether 0 is the appropriate fallback or if an error should be raised.
441-442
: Iterating over sections.
The approach of enumeratingdefinition.sections?.section
intolegacySection, index
is clear and consistent.
444-449
: Passing data sources to field parser.
AddinglegacyDataSourceArray
toparseLegacyFormDefinitionFields
effectively centralizes relevant data for validation.
452-454
: Section IDs and titles.
Auto-generatingsection-${index}
as the ID and using fallback color viatoColor
is a neat pattern.
461-464
: Creating the top-level property map.
UsingcreateLookupTable
ondefinition.properties?.property
makes property retrieval more efficient.
469-470
: Boolean conversion of quickCreate.
.trim() === 'true'
properly normalizes the input to a boolean.
473-479
: New fields for TypeBuilder 2.
AddingdisplayTemplate
,mergeStrategy
,hasJsController
,thumbnailFileName
,isHeadless
, andpaths
extends the type definition.
487-497
: Parsing includes/excludes path arrays.
Returnsnull
if the structure is missing, or an object withpaths.includes
andpaths.excludes
. Straightforward approach.
499-507
: Stubbed fields for legacy content type.
The fields (hasJsController
,isHeadless
,paths
,thumbnailFileName
, etc.) are set tonull
if not in the legacy data.
520-520
: Form definition path creation.
createFormDefinitionPathFromTypeId
usage is consistent with the rest of the calls in this file.
565-569
: Generic usage response interface.
TheFetchContentTypeUsageResponse<T>
interface is flexible through type parameterization.
571-585
: Extended usage fetch.
fetchContentTypeUsage()
now returnsObservable<FetchContentTypeUsageResponse<ContentItem>>
. Correctly merges usage data with content items.
610-610
: Path reusability & binary fetch.
ReusingcreateFormDefinitionPathFromTypeId
for template association/dissociation and fetching preview images keeps the code consistent.Also applies to: 644-644, 665-665
ui/app/src/components/ContentTypeManagement/utils.ts (25)
1-16
: Header license.
These lines introduce the standard open-source GPL v3 license block.
17-42
: Imports and references.
Pulling in many models and utility helpers underscores the file’s core function: bridging content type logic with UI forms.
43-54
: Mapping field properties to XML.
contentTypeFieldToXmlNameMap
clarifies that “name” maps to “title” and “helpText” maps to “help.” Good for consistent serialization.
55-70
:TypePropsToEdit
definition.
This is a focused subset ofContentType
properties, making it easier to manage which fields are editable in the forms.
71-87
:ContentTypeValuesObject
& props array.
The added structure ensures typed data while editing fundamental content type properties.
88-93
:createTypeFormValuesObject()
.
Plucking relevant props from the content type is a succinct approach; hardcodinggroovyController
is acceptable as a placeholder.
94-119
:createTypeFieldValuesObject()
.
Iterating over each relevant field property, ignoring known ephemeral ones (sortable
, etc.) is a clear approach for building form values.
120-133
: Populating field properties.
populateFieldPropertiesValues()
gracefully handles the subset of recognized properties while logging unhandledplugin
usage.
135-149
: Populating validations.
SkippingmaxLength
avoids overwriting from two sources (properties vs. validations). This is a pragmatic workaround.
151-198
: Reversing field values.
reverseTypeFieldValuesObject()
re-injects form data into the originalContentTypeField
. The noted unhandledplugin
property is consistent with the forward parse.
200-221
: Creating an empty type structure.
createEmptyTypeStructure()
with optional mixin ensures flexibility when initializing new content types.
223-242
:createVirtualTypeForField()
.
MergingcommonControlFieldsDescriptors
with existing fields allows on-the-fly creation of a “virtual” content type for a single control.
244-250
:createVirtualTypeForSection()
.
Produces a simplified content type with the given sections. Straightforward.
252-273
: Not implemented data source factory.
createVirtualTypeForDataSource()
explicitly throws an error. Confirm whether you plan to implement this or remove it before merging.
274-284
:createVirtualSection()
.
Auto-generating an ID viananoid()
and applyingtoColor
for the section color is consistent with other logic.
286-298
:createVirtualDataSourceFields()
.
Maps each data source to a content-type field structure. Straightforward approach for bridging data sources into the form.
300-309
: Stable global context.
fooStableGlobalContext
is a frozen object placeholder used for stable references in forms. No issues.
310-330
:createVirtualTypeFormContext()
.
Creates context references, sets up the default values and atoms for each field. Clean approach to building form states.
332-340
:createFieldFormContextApi()
.
Skeleton of a rollback mechanism for forms. Ensure it fully integrates with your forms engine before production.
341-352
:createFieldItemMetaContext()
.
Offers a minimal context about the item, including path, content type, and placeholders for content.
354-390
:createStableFormContextProps()
.
Centralizes the “atoms” for form state (expanded sections, values, etc.). The optionalcreateRootTypeSections
merges extra default sections if needed.
391-398
:makeIntoTypeFieldStructPath()
.
Builds a nested path to reference repeated/child fields. Straightforward splitting and joining logic.
399-454
: Serialization to XML preparation.
prepareSerializeToXmlTypeObject()
andbuildContentTypeXml()
define the final structure for publishing a content type as XML.
455-478
:convertFieldStructToXmlStruct()
.
Currently sets placeholders (undefined
) for plugin, properties, constraints, with a TODO note. Clean approach with clear next steps.
480-506
:convertDataSourceStructToXmlStruct()
.
Iterates through each property and captures its type. Future enhancements might handle custom property types beyond simple boolean/int/string.
ui/app/src/components/FormsEngine/components/TableOfContents.tsx
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/EditTypeViewLayout.tsx
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/EditTypeViewLayout.tsx
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/TypeBuilderFormsEngine.tsx
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/TypeCard.tsx
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/descriptors/archetypes.ts
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/descriptors/archetypes.ts
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/TypeListControlBar.tsx
Outdated
Show resolved
Hide resolved
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (1)
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (1)
138-141
:⚠️ Potential issueMissing functionality in Add Field button.
The "Add Field" button is rendered but doesn't have an onClick handler, so it won't actually do anything when clicked. This appears to be incomplete functionality.
-<TypeBuilderAddButton> +<TypeBuilderAddButton onClick={() => {/* Implement field addition logic */}}> <FormattedMessage defaultMessage="Add Field" /> </TypeBuilderAddButton>
🧹 Nitpick comments (10)
ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx (2)
55-59
: Add empty state handling for search resultsThe component doesn't handle the case when no controls match the search term. Users would see an empty grid with no feedback.
const filteredFields = fieldTypes.filter( (field) => field.name.toLowerCase().includes(searchTerm.toLowerCase()) || field.description.toLowerCase().includes(searchTerm.toLowerCase()) ); return ( <> <DialogBody sx={{ transition: 'height 0.3s ease-in-out' }}> <SearchBar keyword={searchTerm} onChange={handleSearchChange} /> + {filteredFields.length > 0 ? ( <Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}> {filteredFields.map((field, index) => ( // ... existing code ))} </Box> + ) : ( + <Box sx={{ display: 'flex', justifyContent: 'center', padding: 3 }}> + <Typography variant="body2" color="textSecondary"> + <FormattedMessage defaultMessage="No controls match your search" /> + </Typography> + </Box> + )} </DialogBody> </> );
48-48
: Consider adding accessibility improvementsThe dialog should have appropriate ARIA attributes for better accessibility, particularly for screen readers.
Consider adding the following improvements:
- Add
aria-labelledby
to the dialog content referencing the dialog title- Ensure that each control item has appropriate keyboard navigation
- Add a descriptive aria-label to the search bar
ui/app/src/components/ContentTypeManagement/components/TypeDetailsViewHeader.tsx (1)
38-51
: Remove console.log statement from production code.The
handleDeleteType
function includes aconsole.log('Deleted.')
statement in theonComplete
callback. Console logging statements should be removed from production code as they can expose implementation details.onComplete() { - console.log('Deleted.'); onActionClick?.(e, 'deleted'); }
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (3)
93-94
: Fix TypeScript type issue instead of using @ts-expect-error.The code is using
@ts-expect-error
to suppress a TypeScript error. It would be better to fix the underlying type issue for better type safety.-// @ts-expect-error: Handled. Only when it is a button will it receive the onClick. -onClick={isRepeat ? undefined : onClick} +onClick={isRepeat ? undefined : onClick as any}Consider defining proper component type interfaces to avoid type assertions altogether.
98-99
: Same type issue as above needs fixing.Similar to the previous comment, another
@ts-expect-error
is used to suppress TypeScript errors. The same solution applies.
122-122
: Remove empty style object.The
Asterisk
component has an emptysx
object that can be removed.-{error && <Asterisk fontSize="small" sx={{}} />} +{error && <Asterisk fontSize="small" />}ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx (2)
72-75
: Refactor store creation with proper memoization.The TODO comment suggests using "stable memo" for store creation. Since the store is created on every render but only initialized once through the ref pattern, consider using a proper memoization approach.
-const store = useMemo(() => createStore(), []); // TODO: Use stable memo? +const store = useMemo(() => createStore(), []); const stableFormContextRef = useRef<StableFormContextProps>(null); if (stableFormContextRef.current === null) stableFormContextRef.current = createStableFormContextProps({ type }, true);
235-235
: Specify radix in parseInt call.When using parseInt, it's best practice to specify the radix to avoid unexpected results with certain input strings.
-onChange={(e) => setPosition(parseInt(e.target.value))} +onChange={(e) => setPosition(parseInt(e.target.value, 10))}ui/app/src/models/ContentType.ts (2)
165-177
: Document new TypeBuilder 2 properties.Several new properties have been added for TypeBuilder 2, but they have TODOs and limited documentation. Consider adding JSDoc comments for these properties to better document their purpose and expected values.
For example:
+/** + * Indicates whether this content type has a JavaScript controller. + */ hasJsController: boolean; // TODO: Should this one be the file name, like `thumbnailFileName`? +/** + * The filename of the thumbnail image associated with this content type. + */ thumbnailFileName: string;
266-307
: Consider merging similar interfaces as noted in TODO.As noted in the comments,
SerializeToXmlContentTypeStructure
andLegacyFormDefinition
are very similar. Consider whether they can be consolidated or have a shared base interface to reduce duplication.// Base interface with common properties interface BaseContentTypeDefinition { 'content-type': string; title: string; description: string; // ...other common properties } // Extend for specific use cases interface SerializeToXmlContentTypeStructure extends BaseContentTypeDefinition { // ...specific properties } interface LegacyFormDefinition extends BaseContentTypeDefinition { // ...specific properties }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx
(1 hunks)ui/app/src/components/ContentTypeManagement/components/TypeDetailsViewHeader.tsx
(1 hunks)ui/app/src/models/ContentType.ts
(8 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (4)
ui/app/src/models/ContentType.ts (1) (1)
ContentTypeField
(62-140)ui/app/src/hooks/useIsDarkModeTheme.tsx (1) (1)
useIsDarkModeTheme
(20-22)ui/app/src/utils/string.ts (1) (1)
capitalize
(34-36)ui/app/src/components/ContentTypeManagement/components/TypeBuilderAddButton.tsx (1) (1)
TypeBuilderAddButton
(30-30)
ui/app/src/components/ContentTypeManagement/components/TypeDetailsViewHeader.tsx (1)
ui/app/src/models/ContentType.ts (1) (1)
PossibleContentTypeDraft
(187-189)
ui/app/src/components/ContentTypeManagement/components/TypeDetailsView.tsx (5)
ui/app/src/models/ContentType.ts (4) (4)
PossibleContentTypeDraft
(187-189)DataSource
(146-152)ContentTypeSection
(201-210)ContentType
(156-181)ui/app/src/components/ContentTypeManagement/components/TypeDetailsViewHeader.tsx (2) (2)
TypeDetailsViewHeaderProps
(31-34)TypeDetailsViewHeader
(36-100)ui/app/src/components/FormsEngine/lib/formsEngineContext.ts (2) (2)
StableFormContextProps
(107-115)StableFormContext
(125-125)ui/app/src/components/ContentTypeManagement/utils.ts (2) (2)
createVirtualSection
(274-284)createVirtualDataSourceFields
(286-298)ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (1) (1)
defaultDataSourcesSection
(98-102)
ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx (2)
ui/app/src/components/ContentTypeManagement/descriptors/controls/index.ts (1) (1)
controlDescriptors
(148-178)ui/app/src/components/SearchBar/SearchBar.tsx (2) (2)
SearchBarProps
(36-59)SearchBar
(61-204)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (7)
ui/app/src/components/ContentTypeManagement/components/PickControlDialog.tsx (3)
65-74
: Missing selection state for control itemsThe list of controls doesn't track which item is selected, making it impossible to know which control to return when Accept is clicked.
+const [selectedField, setSelectedField] = useState(null); // Then in the mapping function: <ListItemButton key={index} + selected={selectedField === field.id} + onClick={() => setSelectedField(field.id)} >
80-82
: Missing onClick handler for Accept buttonThe Accept button doesn't have an onClick handler to process the selected control. This will prevent users from completing their selection.
-<PrimaryButton> +<PrimaryButton onClick={(e) => { + // Get the selected control and pass it to onClose + const selectedControl = /* logic to get selected control */; + onClose?.(e, selectedControl); +}}> <FormattedMessage defaultMessage="Accept" /> </PrimaryButton>
90-93
: Dialog is always open regardless of propsThe
open
prop is hardcoded totrue
in the EnhancedDialog component, which will cause the dialog to always be open regardless of the actualopen
value passed in props.-<EnhancedDialog open title={<FormattedMessage defaultMessage="Pick a Control" />} maxWidth="sm" {...dialogProps}> +<EnhancedDialog title={<FormattedMessage defaultMessage="Pick a Control" />} maxWidth="sm" {...dialogProps}>ui/app/src/components/ContentTypeManagement/components/TypeDetailsViewHeader.tsx (1)
92-96
: Deletion button logic looks good.The delete button is correctly conditional based on the
NEW
property of the content type, preventing deletion of content types that haven't been saved yet.ui/app/src/components/ContentTypeManagement/components/FieldChip.tsx (1)
56-56
: Plan for performance optimization with atom.The comment indicates a future optimization to make the error check into an atom. This is a good plan for improving performance by avoiding unnecessary re-renders, but should be tracked as a follow-up task.
Are there plans to create a tracking issue for this optimization task?
ui/app/src/models/ContentType.ts (2)
187-189
: Well-defined PossibleContentTypeDraft interface.The interface for
PossibleContentTypeDraft
is well-designed, providing a clear distinction between new and existing content types.
254-256
: Use ofid
in LegacyFormDefinitionSectionWithId is consistent.The addition of the
id
property to sections in theLegacyFormDefinitionSectionWithId
interface is consistent with the changes toContentTypeSection
.
craftercms/craftercms#7418
Summary by CodeRabbit
New Features
Refactor
NewContentDialog
component by removing unused functionality and modifying property handling.Chore