aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorMathieu Suen <59278745+mathieu-suen-sonarsource@users.noreply.github.com>2024-04-22 14:31:11 +0200
committersonartech <sonartech@sonarsource.com>2024-04-22 20:02:38 +0000
commit3a0102ec7c2bcfaf9fa9859e66cd2ef8a94dfd08 (patch)
treed9dc9d66df45065ec447f3245897490274b0030f /server/sonar-web/src/main
parenta827904491975f559a9122503a13be039f242017 (diff)
downloadsonarqube-3a0102ec7c2bcfaf9fa9859e66cd2ef8a94dfd08.tar.gz
sonarqube-3a0102ec7c2bcfaf9fa9859e66cd2ef8a94dfd08.zip
SONAR-22102 Fixing missing udpate of project tags update (#11002)
Diffstat (limited to 'server/sonar-web/src/main')
-rw-r--r--server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx52
2 files changed, 42 insertions, 28 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx b/server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx
index 7d43bf16fd1..81653411f40 100644
--- a/server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx
+++ b/server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx
@@ -17,9 +17,10 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Spinner } from '@sonarsource/echoes-react';
import { MultiSelector, SubHeading, Tags } from 'design-system';
import { difference, without } from 'lodash';
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { searchProjectTags, setApplicationTags, setProjectTags } from '../../../../api/components';
import Tooltip from '../../../../components/controls/Tooltip';
import { PopupPlacement } from '../../../../components/ui/popups';
@@ -33,7 +34,11 @@ interface Props {
}
export default function MetaTags(props: Props) {
- const [open, setOpen] = React.useState(false);
+ const [loading, setLoading] = useState(false);
+
+ useEffect(() => {
+ setLoading(false);
+ }, [props.component.tags]);
const canUpdateTags = () => {
const { configuration } = props.component;
@@ -57,6 +62,7 @@ export default function MetaTags(props: Props) {
};
const handleSetProjectTags = (values: string[]) => {
+ setLoading(true);
setTags(values).then(
() => props.onComponentChange({ tags: values }),
() => {},
@@ -73,13 +79,15 @@ export default function MetaTags(props: Props) {
ariaTagsListLabel={translate('tags')}
className="project-info-tags"
emptyText={translate('no_tags')}
- overlay={<MetaTagsSelector selectedTags={tags} setProjectTags={handleSetProjectTags} />}
+ overlay={
+ <Spinner isLoading={loading}>
+ <MetaTagsSelector selectedTags={tags} setProjectTags={handleSetProjectTags} />
+ </Spinner>
+ }
popupPlacement={PopupPlacement.Bottom}
tags={tags}
tagsToDisplay={2}
tooltip={Tooltip}
- open={open}
- onClose={() => setOpen(false)}
/>
</>
);
diff --git a/server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx b/server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx
index fea012025a3..8267fa68ff1 100644
--- a/server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx
@@ -24,6 +24,7 @@ import { setApplicationTags, setProjectTags } from '../../../../../api/component
import { mockComponent } from '../../../../../helpers/mocks/component';
import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
import { ComponentQualifier } from '../../../../../types/component';
+import { Component } from '../../../../../types/types';
import MetaTags from '../MetaTags';
jest.mock('../../../../../api/components', () => ({
@@ -45,8 +46,6 @@ it('should render without tags and admin rights', async () => {
it('should allow to edit tags for a project', async () => {
const user = userEvent.setup();
-
- const onComponentChange = jest.fn();
const component = mockComponent({
key: 'my-second-project',
tags: ['foo', 'bar'],
@@ -56,7 +55,7 @@ it('should allow to edit tags for a project', async () => {
name: 'MySecondProject',
});
- renderMetaTags({ component, onComponentChange });
+ renderMetaTags(component);
expect(await screen.findByText('foo, bar')).toBeInTheDocument();
expect(screen.getByRole('button')).toBeInTheDocument();
@@ -66,15 +65,11 @@ it('should allow to edit tags for a project', async () => {
expect(await screen.findByRole('checkbox', { name: 'best' })).toBeInTheDocument();
await user.click(screen.getByRole('checkbox', { name: 'best' }));
- expect(onComponentChange).toHaveBeenCalledWith({ tags: ['foo', 'bar', 'best'] });
-
- onComponentChange.mockClear();
+ expect(await screen.findByRole('button', { name: 'foo bar ... +' })).toBeInTheDocument();
- /*
- * Since we're not actually updating the tags, we're back to having the foo, bar only
- */
await user.click(screen.getByRole('checkbox', { name: 'bar' }));
- expect(onComponentChange).toHaveBeenCalledWith({ tags: ['foo'] });
+
+ expect(await screen.findByRole('button', { name: 'foo best +' })).toBeInTheDocument();
expect(setProjectTags).toHaveBeenCalled();
expect(setApplicationTags).not.toHaveBeenCalled();
@@ -85,14 +80,14 @@ it('should allow to edit tags for a project', async () => {
it('should set tags for an app', async () => {
const user = userEvent.setup();
- renderMetaTags({
- component: mockComponent({
+ renderMetaTags(
+ mockComponent({
configuration: {
showSettings: true,
},
qualifier: ComponentQualifier.Application,
}),
- });
+ );
await user.click(screen.getByRole('button', { name: 'no_tags +' }));
@@ -102,14 +97,25 @@ it('should set tags for an app', async () => {
expect(setApplicationTags).toHaveBeenCalled();
});
-function renderMetaTags(overrides: Partial<Parameters<typeof MetaTags>[0]> = {}) {
- const component = mockComponent({
- configuration: {
- showSettings: false,
- },
- });
-
- return renderComponent(
- <MetaTags component={component} onComponentChange={jest.fn()} {...overrides} />,
- );
+function renderMetaTags(componentOverride: Partial<Component> = {}) {
+ function Component(componentOverride: Partial<Parameters<typeof MetaTags>[0]>) {
+ const [component, setComponent] = React.useState(
+ mockComponent({
+ configuration: {
+ showSettings: false,
+ },
+ ...componentOverride,
+ }),
+ );
+
+ const handleComponentChange = ({ tags }: { tags: string[] }) => {
+ setComponent((c) => {
+ return { ...c, tags };
+ });
+ };
+
+ return <MetaTags component={component} onComponentChange={handleComponentChange} />;
+ }
+
+ return renderComponent(<Component {...componentOverride} />);
}