This is an automated email from the ASF dual-hosted git repository.
mcgilman pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 8cc7f0d5184 NIFI-15920 improve accesibility around connector state
text in listing (#11225)
8cc7f0d5184 is described below
commit 8cc7f0d5184ebbe047a03f61221857edba8cc5d7
Author: Scott Aslan <[email protected]>
AuthorDate: Wed May 13 17:20:24 2026 -0400
NIFI-15920 improve accesibility around connector state text in listing
(#11225)
* NIFI-15920 improve accesibility around connector state text in listing
* add status badge and status variant
* address review feedback
---
.../connector-table/connector-table.component.html | 13 ++--
.../connector-table/connector-table.component.ts | 16 ++++-
.../libs/shared/src/assets/themes/material.scss | 48 ++++++++++++++
.../connector-detail-header.component.html | 13 ++--
.../connector-detail-header.component.spec.ts | 76 ++--------------------
.../connector-detail-header.component.ts | 44 ++-----------
.../frontend/libs/shared/src/components/index.ts | 1 +
.../status-badge/status-badge.component.html | 28 ++++++++
.../status-badge/status-badge.component.scss | 42 ++++++++++++
.../status-badge/status-badge.component.spec.ts | 38 +++++++++++
.../status-badge/status-badge.component.ts | 32 +++++++++
.../src/utils/connector-permissions.utils.spec.ts | 47 ++++++++++++-
.../src/utils/connector-permissions.utils.ts | 22 ++++++-
13 files changed, 292 insertions(+), 128 deletions(-)
diff --git
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.html
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.html
index b7b9df27448..91d2e95578e 100644
---
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.html
+++
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.html
@@ -74,11 +74,16 @@
<th mat-header-cell *matHeaderCellDef
mat-sort-header>State</th>
<td mat-cell *matCellDef="let item"
data-qa="connector-state-cell">
<div class="inline-flex items-center gap-x-2">
- <span [title]="formatState(item)">{{ formatState(item)
}}</span>
+ @if (canRead(item)) {
+ <status-badge
+ [label]="formatState(item)"
+
[variant]="getConnectorStateVariant(item.component.state)"
+ data-qa="connector-state">
+ </status-badge>
+ }
@if (canRead(item) && canDiscardConfig(item)) {
- <span class="caution-color text-xs font-medium"
data-qa="edits-not-applied-badge"
- >(Edits not applied)</span
- >
+ <status-badge label="Edits not applied"
variant="caution" data-qa="edits-not-applied-badge">
+ </status-badge>
}
</div>
</td>
diff --git
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.ts
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.ts
index e2d52960668..fb04927180a 100644
---
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.ts
+++
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/connectors/ui/connector-table/connector-table.component.ts
@@ -26,11 +26,13 @@ import {
ConnectorActionName,
NifiTooltipDirective,
NiFiCommon,
+ StatusBadge,
canReadConnector,
canModifyConnector,
canOperateConnector,
isConnectorActionAllowed,
- getConnectorActionDisabledReason
+ getConnectorActionDisabledReason,
+ getConnectorStateVariant
} from '@nifi/shared';
import { ValidationErrorsTipInput } from '../../../../state/shared';
import { FlowConfiguration } from '../../../../state/flow-configuration';
@@ -41,7 +43,15 @@ import { ValidationErrorsTip } from
'../../../../ui/common/tooltips/validation-e
selector: 'connector-table',
standalone: true,
templateUrl: './connector-table.component.html',
- imports: [MatButtonModule, MatTableModule, MatSortModule, MatMenuModule,
MatTooltipModule, NifiTooltipDirective],
+ imports: [
+ MatButtonModule,
+ MatTableModule,
+ MatSortModule,
+ MatMenuModule,
+ MatTooltipModule,
+ NifiTooltipDirective,
+ StatusBadge
+ ],
styleUrls: ['./connector-table.component.scss']
})
export class ConnectorTable {
@@ -113,6 +123,8 @@ export class ConnectorTable {
return getConnectorActionDisabledReason(entity, actionName);
}
+ protected readonly getConnectorStateVariant = getConnectorStateVariant;
+
canConfigure(entity: ConnectorEntity): boolean {
return isConnectorActionAllowed(entity, 'CONFIGURE');
}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/assets/themes/material.scss
b/nifi-frontend/src/main/frontend/libs/shared/src/assets/themes/material.scss
index be93da637a4..5f6e7b73c7c 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/assets/themes/material.scss
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/assets/themes/material.scss
@@ -361,6 +361,30 @@
)
);
}
+
+ // NOTE: The following styles are for the status badge and status banner
components. The `.status-variant` class should only be applied to a div or span
element that should adhear to the variant color and background.
+ .status-variant {
+ &.neutral {
+ color: var(--mat-sys-on-surface);
+ background-color: var(--mat-sys-surface-dim);
+ }
+ &.critical {
+ color: var(--mat-sys-on-error);
+ background-color: var(--mat-sys-error);
+ }
+ &.caution {
+ color: var(--nf-caution-contrast);
+ background-color: var(--nf-caution-default);
+ }
+ &.success {
+ color: var(--nf-success-contrast);
+ background-color: var(--nf-success-default);
+ }
+ &.info {
+ color: var(--nf-success-contrast);
+ background-color: var(--nf-success-variant);
+ }
+ }
}
// Note: Color palettes are generated from primary: #6750a4
@@ -854,4 +878,28 @@ html {
)
);
}
+
+ // NOTE: The following styles are for the status badge and status banner
components. The `.status-variant` class should only be applied to a div or span
element that should adhear to the variant color and background.
+ .status-variant {
+ &.neutral {
+ color: var(--mat-sys-on-surface);
+ background-color: var(--mat-sys-surface-dim);
+ }
+ &.critical {
+ color: var(--mat-sys-on-error);
+ background-color: var(--mat-sys-error);
+ }
+ &.caution {
+ color: var(--nf-caution-contrast);
+ background-color: var(--nf-caution-default);
+ }
+ &.success {
+ color: var(--nf-success-contrast);
+ background-color: var(--nf-success-default);
+ }
+ &.info {
+ color: var(--nf-success-contrast);
+ background-color: var(--nf-success-variant);
+ }
+ }
}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.html
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.html
index 7ecf984d0a3..4cb8a7fc210 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.html
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.html
@@ -16,16 +16,13 @@
-->
<ng-template #badges>
- <span
- class="connector-state-badge text-xs font-semibold uppercase"
- [class]="getStateColorClass(connector().component.state)"
+ <status-badge
+ [label]="connector().component.state"
+ [variant]="getStateVariant(connector().component.state)"
data-qa="connector-state">
- {{ connector().component.state }}
- </span>
+ </status-badge>
@if (hasUnappliedEdits()) {
- <span class="caution-color text-xs font-semibold uppercase"
data-qa="edits-not-applied-badge">
- Edits not applied
- </span>
+ <status-badge label="Edits not applied" variant="caution"
data-qa="edits-not-applied-badge"> </status-badge>
}
</ng-template>
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.spec.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.spec.ts
index 65321dd24b3..35961829f9c 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.spec.ts
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.spec.ts
@@ -18,6 +18,7 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ConnectorDetailHeader } from './connector-detail-header.component';
import { ConnectorEntity, ConnectorState, ConnectorStatus } from '../../types';
+import { getConnectorStateVariant } from
'../../utils/connector-permissions.utils';
interface SetupOptions {
connector?: ConnectorEntity;
@@ -108,78 +109,9 @@ describe('ConnectorDetailHeader', () => {
expect(stateBadge.textContent.trim()).toBe('RUNNING');
});
- describe('getStateVariant', () => {
- it('should return success for RUNNING', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.RUNNING)).toBe('success');
- });
-
- it('should return neutral for STOPPED', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.STOPPED)).toBe('neutral');
- });
-
- it('should return neutral for DISABLED', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.DISABLED)).toBe('neutral');
- });
-
- it('should return info for STARTING', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.STARTING)).toBe('info');
- });
-
- it('should return info for UPDATING', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.UPDATING)).toBe('info');
- });
-
- it('should return info for STOPPING', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.STOPPING)).toBe('info');
- });
-
- it('should return info for DRAINING', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.DRAINING)).toBe('info');
- });
-
- it('should return info for PREPARING_FOR_UPDATE', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.PREPARING_FOR_UPDATE)).toBe('info');
- });
-
- it('should return critical for UPDATE_FAILED', async () => {
- const { component } = await setup();
-
expect(component.getStateVariant(ConnectorState.UPDATE_FAILED)).toBe('critical');
- });
-
- it('should return neutral for unknown state', async () => {
- const { component } = await setup();
- expect(component.getStateVariant('UNKNOWN')).toBe('neutral');
- });
- });
-
- describe('getStateColorClass', () => {
- it('should map success variant to success-color-default', async () => {
- const { component } = await setup();
-
expect(component.getStateColorClass(ConnectorState.RUNNING)).toBe('success-color-default');
- });
-
- it('should map neutral variant to neutral-color', async () => {
- const { component } = await setup();
-
expect(component.getStateColorClass(ConnectorState.STOPPED)).toBe('neutral-color');
- });
-
- it('should map info variant to primary-color', async () => {
- const { component } = await setup();
-
expect(component.getStateColorClass(ConnectorState.STARTING)).toBe('primary-color');
- });
-
- it('should map critical variant to error-color', async () => {
- const { component } = await setup();
-
expect(component.getStateColorClass(ConnectorState.UPDATE_FAILED)).toBe('error-color');
- });
+ it('should delegate getStateVariant to getConnectorStateVariant', async ()
=> {
+ const { component } = await setup();
+ expect(component.getStateVariant).toBe(getConnectorStateVariant);
});
describe('hasUnappliedEdits', () => {
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.ts
index 6c55abceace..6ef715607be 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.ts
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/connector-detail-header/connector-detail-header.component.ts
@@ -17,14 +17,14 @@
import { Component, computed, input } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
-import { ConnectorEntity, ConnectorState } from '../../types';
-
-export type ConnectorStateVariant = 'neutral' | 'critical' | 'caution' |
'success' | 'info';
+import { ConnectorEntity } from '../../types';
+import { StatusBadge } from '../status-badge/status-badge.component';
+import { getConnectorStateVariant } from
'../../utils/connector-permissions.utils';
@Component({
selector: 'connector-detail-header',
standalone: true,
- imports: [NgTemplateOutlet],
+ imports: [NgTemplateOutlet, StatusBadge],
templateUrl: './connector-detail-header.component.html',
styleUrls: ['./connector-detail-header.component.scss']
})
@@ -48,39 +48,5 @@ export class ConnectorDetailHeader {
return action?.allowed ?? false;
});
- getStateVariant(state: string): ConnectorStateVariant {
- switch (state) {
- case ConnectorState.RUNNING:
- return 'success';
- case ConnectorState.STOPPED:
- case ConnectorState.DISABLED:
- return 'neutral';
- case ConnectorState.STARTING:
- case ConnectorState.UPDATING:
- case ConnectorState.STOPPING:
- case ConnectorState.DRAINING:
- case ConnectorState.PREPARING_FOR_UPDATE:
- return 'info';
- case ConnectorState.UPDATE_FAILED:
- return 'critical';
- default:
- return 'neutral';
- }
- }
-
- getStateColorClass(state: string): string {
- switch (this.getStateVariant(state)) {
- case 'success':
- return 'success-color-default';
- case 'critical':
- return 'error-color';
- case 'caution':
- return 'caution-color';
- case 'info':
- return 'primary-color';
- case 'neutral':
- default:
- return 'neutral-color';
- }
- }
+ protected readonly getStateVariant = getConnectorStateVariant;
}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts
index 2ffa339d64a..112731a7a43 100644
--- a/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts
+++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts
@@ -46,5 +46,6 @@ export * from
'./side-panel-container/side-panel-container.component';
export * from './connector-property-input/connector-property-input.component';
export * from './connector-detail-header/connector-detail-header.component';
export * from './searchable-select/searchable-select.component';
+export * from './status-badge/status-badge.component';
export * from './multi-select-option/multi-select-option.component';
export * from './asset-upload/asset-upload.component';
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.html
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.html
new file mode 100644
index 00000000000..2a40397035b
--- /dev/null
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.html
@@ -0,0 +1,28 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+@if (label) {
+ <span
+ class="status-badge status-variant py-0.5 px-1.5 rounded-xs
items-center inline-flex text-sm font-semibold max-h-fit max-w-fit gap-0.5
cursor-default"
+ [class]="variant"
+ [matTooltip]="message">
+ {{ label }}
+ @if (message && message.length > 0) {
+ <i class="fa fa-info text-[16px]" [class]="variant"></i>
+ }
+ </span>
+}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.scss
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.scss
new file mode 100644
index 00000000000..1cead2c5dbe
--- /dev/null
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.scss
@@ -0,0 +1,42 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@use '@angular/material' as mat;
+
+.status-badge {
+ .fa {
+ &.neutral {
+ color: var(--mat-sys-on-surface);
+ }
+
+ &.critical {
+ color: var(--mat-sys-on-error);
+ }
+
+ &.caution {
+ color: var(--nf-caution-contrast);
+ }
+
+ &.success {
+ color: var(--nf-success-contrast);
+ }
+
+ &.info {
+ color: var(--nf-success-contrast);
+ }
+ }
+}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.spec.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.spec.ts
new file mode 100644
index 00000000000..d147d37bc01
--- /dev/null
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.spec.ts
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { StatusBadge } from './status-badge.component';
+
+describe('StatusBadge', () => {
+ let component: StatusBadge;
+ let fixture: ComponentFixture<StatusBadge>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [StatusBadge]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(StatusBadge);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.ts
new file mode 100644
index 00000000000..af1147b4f86
--- /dev/null
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/components/status-badge/status-badge.component.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, Input } from '@angular/core';
+import { StatusVariant } from '../../types';
+import { MatTooltip } from '@angular/material/tooltip';
+
+@Component({
+ selector: 'status-badge',
+ imports: [MatTooltip],
+ templateUrl: './status-badge.component.html',
+ styleUrls: ['./status-badge.component.scss']
+})
+export class StatusBadge {
+ @Input() label: string | null = null;
+ @Input() variant: StatusVariant = 'neutral';
+ @Input() message: string | null | undefined = null;
+}
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.spec.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.spec.ts
index dc8959f7f75..f4e61db6454 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.spec.ts
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.spec.ts
@@ -15,14 +15,15 @@
* limitations under the License.
*/
-import { ConnectorEntity } from '../types';
+import { ConnectorEntity, ConnectorState } from '../types';
import {
canReadConnector,
canModifyConnector,
canOperateConnector,
getConnectorAction,
isConnectorActionAllowed,
- getConnectorActionDisabledReason
+ getConnectorActionDisabledReason,
+ getConnectorStateVariant
} from './connector-permissions.utils';
function createMockEntity(overrides: Partial<ConnectorEntity> = {}):
ConnectorEntity {
@@ -182,4 +183,46 @@ describe('connector-permissions.utils', () => {
expect(getConnectorActionDisabledReason(entity, 'START')).toBe('');
});
});
+
+ describe('getConnectorStateVariant', () => {
+ it('should return success for RUNNING', () => {
+
expect(getConnectorStateVariant(ConnectorState.RUNNING)).toBe('success');
+ });
+
+ it('should return neutral for STOPPED', () => {
+
expect(getConnectorStateVariant(ConnectorState.STOPPED)).toBe('neutral');
+ });
+
+ it('should return neutral for DISABLED', () => {
+
expect(getConnectorStateVariant(ConnectorState.DISABLED)).toBe('neutral');
+ });
+
+ it('should return info for STARTING', () => {
+
expect(getConnectorStateVariant(ConnectorState.STARTING)).toBe('info');
+ });
+
+ it('should return info for UPDATING', () => {
+
expect(getConnectorStateVariant(ConnectorState.UPDATING)).toBe('info');
+ });
+
+ it('should return info for STOPPING', () => {
+
expect(getConnectorStateVariant(ConnectorState.STOPPING)).toBe('info');
+ });
+
+ it('should return info for DRAINING', () => {
+
expect(getConnectorStateVariant(ConnectorState.DRAINING)).toBe('info');
+ });
+
+ it('should return info for PREPARING_FOR_UPDATE', () => {
+
expect(getConnectorStateVariant(ConnectorState.PREPARING_FOR_UPDATE)).toBe('info');
+ });
+
+ it('should return critical for UPDATE_FAILED', () => {
+
expect(getConnectorStateVariant(ConnectorState.UPDATE_FAILED)).toBe('critical');
+ });
+
+ it('should return neutral for unknown state', () => {
+ expect(getConnectorStateVariant('UNKNOWN')).toBe('neutral');
+ });
+ });
});
diff --git
a/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.ts
b/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.ts
index bffe16bdc17..d78f5f31478 100644
---
a/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.ts
+++
b/nifi-frontend/src/main/frontend/libs/shared/src/utils/connector-permissions.utils.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { ConnectorAction, ConnectorActionName, ConnectorEntity } from
'../types';
+import { ConnectorAction, ConnectorActionName, ConnectorEntity,
ConnectorState, StatusVariant } from '../types';
export function canReadConnector(entity: ConnectorEntity): boolean {
return entity.permissions.canRead;
@@ -45,3 +45,23 @@ export function getConnectorActionDisabledReason(entity:
ConnectorEntity, action
const action = getConnectorAction(entity, actionName);
return action?.reasonNotAllowed ?? '';
}
+
+export function getConnectorStateVariant(state: string): StatusVariant {
+ switch (state) {
+ case ConnectorState.RUNNING:
+ return 'success';
+ case ConnectorState.STOPPED:
+ case ConnectorState.DISABLED:
+ return 'neutral';
+ case ConnectorState.STARTING:
+ case ConnectorState.UPDATING:
+ case ConnectorState.STOPPING:
+ case ConnectorState.DRAINING:
+ case ConnectorState.PREPARING_FOR_UPDATE:
+ return 'info';
+ case ConnectorState.UPDATE_FAILED:
+ return 'critical';
+ default:
+ return 'neutral';
+ }
+}