Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: place icon for StudioProperty.Button next to label #14431

Merged
merged 10 commits into from
Jan 21, 2025
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.propertyButton {
border-radius: 0;
display: flex;
display: grid;
grid-template-columns: 1fr auto;
justify-content: flex-start;
margin: calc(-1 * var(--studio-property-button-vertical-spacing)) 0;
overflow: hidden;
padding: var(--studio-property-button-vertical-spacing) var(--fds-spacing-5);
padding: var(--studio-property-button-vertical-spacing) var(--fds-spacing-3);
}

.propertyButton.withValue .content {
Expand Down Expand Up @@ -58,3 +58,7 @@
.propertyButton.withoutNegativeMargin {
margin: 0;
}

.definedValue {
color: var(--fds-semantic-text-neutral-default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const StudioPropertyButton = forwardRef<HTMLButtonElement, StudioPropertyButtonP
compact && classes.compact,
readOnly && classes.readOnly,
withoutNegativeMargin && classes.withoutNegativeMargin,
givenIcon && hasValue && classes.definedValue,
givenClass,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export const EditActions = (): React.ReactElement => {
<StudioProperty.Button
onClick={onNewActionAddClicked}
property={t('process_editor.configuration_panel_actions_add_new')}
size='small'
/>
</>
);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { StudioProperty } from '@studio/components';
import { useTranslation } from 'react-i18next';
import { LinkIcon } from '@studio/icons';
import { SelectDataTypes } from './SelectDataTypes';
import classes from './EditDataTypes.module.css';
import { useBpmnContext } from '../../../../contexts/BpmnContext';

export type EditDataTypesProps = {
Expand All @@ -27,19 +26,12 @@ export const EditDataTypes = ({
setDataModelSelectVisible(false);
}, [bpmnDetails.id]);

const definedValueWithLinkIcon = (
<span className={classes.definedValue}>
<LinkIcon /> {existingDataTypeForTask}
</span>
);

return (
<>
{!existingDataTypeForTask && !dataModelSelectVisible ? (
<StudioProperty.Button
onClick={() => setDataModelSelectVisible(true)}
property={t('process_editor.configuration_panel_set_data_model_link')}
size='small'
icon={<LinkIcon />}
/>
) : dataModelSelectVisible ? (
Expand All @@ -55,9 +47,10 @@ export const EditDataTypes = ({
aria-label={t('process_editor.configuration_panel_set_data_model', {
dataModelName: existingDataTypeForTask,
})}
icon={<LinkIcon />}
onClick={() => setDataModelSelectVisible(true)}
property={t('process_editor.configuration_panel_set_data_model_label')}
value={definedValueWithLinkIcon}
value={existingDataTypeForTask}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const EditUniqueFromSignaturesInDataTypes = () => {
property={t(
'process_editor.configuration_panel_set_unique_from_signatures_in_data_types_link',
)}
size='small'
icon={<PersonPencilIcon />}
/>
) : isSelectVisible ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const CustomReceiptContent = (): React.ReactElement => {
return (
<StudioProperty.Button
onClick={openCustomReceiptFields}
size='small'
property={t('process_editor.configuration_panel_custom_receipt_create_your_own_button')}
className={classes.createButton}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
flex-direction: column;
background-color: var(--fds-semantic-surface-neutral-default);
gap: var(--fds-spacing-2);
padding-bottom: var(--fds-spacing-2);
align-items: flex-start;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

.button {
margin: var(--fds-spacing-1);
align-items: center;
padding-left: 0;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
.selectedOption {
align-items: center;
display: flex;
gap: var(--fds-spacing-1);
}

.error {
background-color: var(--fds-semantic-surface-danger-subtle);
}

.currentLinkedDataModel {
text-overflow: ellipsis;
overflow: hidden;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import { screen, waitForElementToBeRemoved, within } from '@testing-library/reac
import { textMock } from '@studio/testing/mocks/i18nMock';
import type { QueryClient } from '@tanstack/react-query';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { QueryKey } from 'app-shared/types/QueryKey';
import { app, org } from '@studio/testing/testids';
import type { ServicesContextProps } from 'app-shared/contexts/ServicesContext';

const label = 'label';
const dataModelField = 'field';
const dataModel = 'model';
const bindingKey = 'bindingKey';

const defaultDefinedBinding: DefinedBindingProps = {
const defaultDefinedBindingProps: DefinedBindingProps = {
label,
onClick: jest.fn(),
internalBindingFormat: {
Expand All @@ -25,19 +27,19 @@ const defaultDefinedBinding: DefinedBindingProps = {
};

type RenderDefinedBinding = {
props?: DefinedBindingProps;
props?: Partial<DefinedBindingProps>;
queryClient?: QueryClient;
queries?: Partial<ServicesContextProps>;
};

const renderDefinedBinding = ({
props = defaultDefinedBinding,
props,
queryClient = createQueryClientMock(),
queries,
}: RenderDefinedBinding) => {
}: RenderDefinedBinding = {}) => {
return {
...renderWithProviders(<DefinedBinding {...props} />, {
queries: { ...queries },
...renderWithProviders(<DefinedBinding {...defaultDefinedBindingProps} {...props} />, {
queries,
queryClient,
}),
};
Expand All @@ -49,7 +51,7 @@ describe('DefinedBinding', () => {
});

it('should render loading spinner', async () => {
renderDefinedBinding({});
renderDefinedBinding();
const loadingSpinnerTitle = textMock('ux_editor.modal_properties_loading');

const loadingSpinner = screen.getByTitle(loadingSpinnerTitle);
Expand All @@ -59,7 +61,7 @@ describe('DefinedBinding', () => {
});

it('should render edit button with the binding selected', async () => {
renderDefinedBinding({});
renderDefinedBinding();

await waitForElementToBeRemoved(() =>
screen.queryByTitle(textMock('ux_editor.modal_properties_loading')),
Expand All @@ -77,7 +79,6 @@ describe('DefinedBinding', () => {
it('should render edit button with the binding selected even with no data model selected', async () => {
renderDefinedBinding({
props: {
...defaultDefinedBinding,
internalBindingFormat: {
field: dataModelField,
dataType: '',
Expand All @@ -97,4 +98,48 @@ describe('DefinedBinding', () => {
const editButtonText = within(editButton).getByText(dataModelField);
expect(editButtonText).toBeInTheDocument();
});

it('should render with error css class when selected data model does not exist', async () => {
renderWithDataModelAndMetadata('non-existent-model', dataModelField);
await waitForElementToBeRemoved(() =>
screen.queryByTitle(textMock('ux_editor.modal_properties_loading')),
);
const editButton = screen.getByRole('button', {
name: textMock('right_menu.data_model_bindings_edit', { binding: label }),
});
expect(editButton).toHaveClass('error');
});

it('should render with error css class when selected data model field does not exist in model', async () => {
renderWithDataModelAndMetadata(dataModel, 'non-existent-field');
await waitForElementToBeRemoved(() =>
screen.queryByTitle(textMock('ux_editor.modal_properties_loading')),
);
const editButton = screen.getByRole('button', {
name: textMock('right_menu.data_model_bindings_edit', { binding: label }),
});
expect(editButton).toHaveClass('error');
});

it('should render without error css class when selected data model and field is valid', async () => {
renderWithDataModelAndMetadata(dataModel, dataModelField);
await waitForElementToBeRemoved(() =>
screen.queryByTitle(textMock('ux_editor.modal_properties_loading')),
);
const editButton = screen.getByRole('button', {
name: textMock('right_menu.data_model_bindings_edit', { binding: label }),
});
expect(editButton).not.toHaveClass('error');
});
});

const renderWithDataModelAndMetadata = (modelName: string, fieldName: string) => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.AppMetadataModelIds, org, app, false], [modelName]);
const getDataModelMetadata = jest
.fn()
.mockImplementation(() =>
Promise.resolve({ elements: { [fieldName]: { dataBindingName: fieldName, maxOccurs: 0 } } }),
);
renderDefinedBinding({ queries: { getDataModelMetadata }, queryClient });
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,17 @@ export const DefinedBinding = ({

const dataModelFields = getDataModelFields({ componentType, bindingKey, dataModelMetadata });
const isFieldValid = validateSelectedDataField(currentDataModelField, dataModelFields);

const isBindingError = !isFieldValid || !isDataModelValid;

const value = (
<span className={classes.selectedOption}>
<LinkIcon /> <span className={classes.currentLinkedDataModel}>{currentDataModelField}</span>
</span>
);

return (
<StudioProperty.Button
className={`${isBindingError ? classes.error : ''}`}
className={isBindingError ? classes.error : ''}
aria-label={title}
onClick={onClick}
property={label}
title={title}
value={value}
icon={<LinkIcon />}
value={currentDataModelField}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.texts {
margin-bottom: var(--fds-spacing-7);
margin-bottom: var(--fds-spacing-3);
gap: 0;
}
Loading