new Client->details->ClientScopes and ClientScopes tests (#1967)

This commit is contained in:
ikhomyn 2022-02-22 13:46:49 +01:00 committed by GitHub
parent 27ed3e40fe
commit 83d9018f6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 593 additions and 45 deletions

View file

@ -1,9 +1,16 @@
import LoginPage from "../support/pages/LoginPage";
import Masthead from "../support/pages/admin_console/Masthead";
import ListingPage from "../support/pages/admin_console/ListingPage";
import ListingPage, {
Filter,
FilterAssignedType,
FilterProtocol,
} from "../support/pages/admin_console/ListingPage";
import SidebarPage from "../support/pages/admin_console/SidebarPage";
import CreateClientScopePage from "../support/pages/admin_console/manage/client_scopes/CreateClientScopePage";
import { keycloakBefore } from "../support/util/keycloak_hooks";
import {
keycloakBefore,
keycloakBeforeEach,
} from "../support/util/keycloak_hooks";
import RoleMappingTab from "../support/pages/admin_console/manage/RoleMappingTab";
import ModalUtils from "../support/util/ModalUtils";
import AdminClient from "../support/util/AdminClient";
@ -17,56 +24,261 @@ const createClientScopePage = new CreateClientScopePage();
const modalUtils = new ModalUtils();
describe("Client Scopes test", () => {
describe("Client Scope list items ", () => {
const clientScopeName = "client-scope-test";
const clientScope = {
name: clientScopeName,
description: "",
protocol: "openid-connect",
attributes: {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"gui.order": "1",
"consent.screen.text": "",
},
};
const modalMessageDeleteConfirmation =
"Are you sure you want to delete this client scope";
const notificationMessageDeletionConfirmation =
"The client scope has been deleted";
const clientScopeName = "client-scope-test";
const openIDConnectItemText = "OpenID Connect";
const clientScope = {
name: clientScopeName,
description: "",
protocol: "openid-connect",
attributes: {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"gui.order": "1",
"consent.screen.text": "",
},
};
before(async () => {
const client = new AdminClient();
for (let i = 0; i < 5; i++) {
clientScope.name = clientScopeName + i;
await client.createClientScope(clientScope);
before(async () => {
const client = new AdminClient();
for (let i = 0; i < 5; i++) {
clientScope.name = clientScopeName + i;
await client.createClientScope(clientScope);
}
});
after(async () => {
const client = new AdminClient();
for (let i = 0; i < 5; i++) {
if (await client.existsClientScope(clientScopeName + i)) {
await client.deleteClientScope(clientScopeName + i);
}
}
});
describe("Client Scope filter list items", () => {
before(() => {
keycloakBefore();
loginPage.logIn();
});
beforeEach(() => {
keycloakBefore();
loginPage.logIn();
keycloakBeforeEach();
sidebarPage.goToClientScopes();
});
after(async () => {
const client = new AdminClient();
for (let i = 0; i < 5; i++) {
await client.deleteClientScope(clientScopeName + i);
}
it("should filter item by name", () => {
const itemName = clientScopeName + 0;
listingPage
.searchItem(itemName, false)
.itemsEqualTo(1)
.itemExist(itemName, true);
});
it("should filter items by Assigned type All types", () => {
listingPage
.selectFilter(Filter.AssignedType)
.selectSecondaryFilterAssignedType(FilterAssignedType.AllTypes)
.itemExist(FilterAssignedType.Default, true)
.itemExist(FilterAssignedType.Optional, true)
.itemExist(FilterAssignedType.None, true);
});
it("should filter items by Assigned type Default", () => {
listingPage
.selectFilter(Filter.AssignedType)
.selectSecondaryFilterAssignedType(FilterAssignedType.Default)
.itemExist(FilterAssignedType.Default, true)
.itemExist(FilterAssignedType.Optional, false)
.itemExist(FilterAssignedType.None, false);
});
it("should filter items by Assigned type Optional", () => {
listingPage
.selectFilter(Filter.AssignedType)
.selectSecondaryFilterAssignedType(FilterAssignedType.Optional)
.itemExist(FilterAssignedType.Default, false)
.itemExist(FilterAssignedType.Optional, true)
.itemExist(FilterAssignedType.None, false);
});
//TODO https://github.com/keycloak/keycloak-admin-ui/issues/1959
it("should filter items by Protocol All", () => {
listingPage
.selectFilter(Filter.Protocol)
.selectSecondaryFilterProtocol(FilterProtocol.All)
.showNextPageTableItems()
.itemExist(FilterProtocol.SAML, true)
.itemExist(openIDConnectItemText, true); //using FilterProtocol.OpenID will fail, text does not match.
});
//TODO https://github.com/keycloak/keycloak-admin-ui/issues/1959
it("should filter items by Protocol SAML", () => {
listingPage
.selectFilter(Filter.Protocol)
.selectSecondaryFilterProtocol(FilterProtocol.SAML)
.itemExist(FilterProtocol.SAML, true)
.itemExist(openIDConnectItemText, false); //using FilterProtocol.OpenID will fail, text does not match.
});
//TODO https://github.com/keycloak/keycloak-admin-ui/issues/1959
it("should filter items by Protocol OpenID", () => {
listingPage
.selectFilter(Filter.Protocol)
.selectSecondaryFilterProtocol(FilterProtocol.OpenID)
.itemExist(FilterProtocol.SAML, false)
.itemExist(openIDConnectItemText, true); //using FilterProtocol.OpenID will fail, text does not match.
});
it("should show items on next page are more than 11", () => {
listingPage.showNextPageTableItems();
listingPage.itemsGreaterThan(1);
});
});
cy.get(listingPage.tableRowItem).its("length").should("be.gt", 1);
describe("Client Scope modify list items", () => {
const itemName = clientScopeName + 0;
before(() => {
keycloakBefore();
loginPage.logIn();
});
beforeEach(() => {
keycloakBeforeEach();
sidebarPage.goToClientScopes();
});
it("should modify selected item type to Default from search bar", () => {
listingPage
.clickItemCheckbox(itemName)
.changeTypeToOfSelectedItems(FilterAssignedType.Default);
listingPage.itemContainValue(itemName, 2, FilterAssignedType.Default);
});
it("should modify selected item type to Optional from search bar", () => {
listingPage
.clickItemCheckbox(itemName)
.changeTypeToOfSelectedItems(FilterAssignedType.Optional);
listingPage.itemContainValue(itemName, 2, FilterAssignedType.Optional);
});
const expectedItemAssignedTypes = [
FilterAssignedType.Default,
FilterAssignedType.Optional,
FilterAssignedType.None,
];
expectedItemAssignedTypes.forEach(($assignedType) => {
const itemName = clientScopeName + 0;
it(`should modify item ${itemName} AssignedType to ${$assignedType} from item bar`, () => {
listingPage
.searchItem(clientScopeName, false)
.clickRowSelectItem(itemName, $assignedType);
// sidebarPage.waitForPageLoad(); //not working
cy.wait(2000);
listingPage.searchItem(itemName, false).itemExist($assignedType);
});
});
it("should not allow to modify item AssignedType from search bar when no item selected", () => {
const itemName = clientScopeName + 0;
listingPage
.searchItem(itemName, false)
.checkInSearchBarChangeTypeToButtonIsDisabled()
.clickSearchBarActionButton()
.checkDropdownItemIsDisabled("Delete")
.clickItemCheckbox(itemName)
.checkInSearchBarChangeTypeToButtonIsDisabled(false)
.clickSearchBarActionButton()
.checkDropdownItemIsDisabled("Delete", false)
.clickItemCheckbox(itemName)
.checkInSearchBarChangeTypeToButtonIsDisabled()
.clickSearchBarActionButton()
.checkDropdownItemIsDisabled("Delete");
});
//TODO: blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1952
//it("should export item from item bar", () => {
//});
});
describe("Client Scope delete list items ", () => {
before(() => {
keycloakBefore();
loginPage.logIn();
});
beforeEach(() => {
keycloakBeforeEach();
sidebarPage.goToClientScopes();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete item from item bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
.clickItemCheckbox(clientScopeName + 0)
.deleteItem(clientScopeName + 0);
modalUtils
.checkModalMessage(modalMessageDeleteConfirmation)
.confirmModal();
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete selected item from search bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
.clickItemCheckbox(clientScopeName + 1)
.clickSearchBarActionButton()
.clickSearchBarActionItem("Delete");
modalUtils
.checkModalMessage(modalMessageDeleteConfirmation)
.confirmModal();
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete multiple selected items from search bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
.clickItemCheckbox(clientScopeName + 2)
.clickItemCheckbox(clientScopeName + 3)
.clickItemCheckbox(clientScopeName + 4)
.clickSearchBarActionButton()
.clickSearchBarActionItem("Delete");
modalUtils
.checkModalMessage(modalMessageDeleteConfirmation)
.confirmModal();
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
});
describe("Client Scope creation", () => {
beforeEach(() => {
before(() => {
keycloakBefore();
loginPage.logIn();
});
beforeEach(() => {
keycloakBeforeEach();
sidebarPage.goToClientScopes();
});
it("should fail creating client scope", () => {
sidebarPage.waitForPageLoad();
listingPage.goToCreateItem();
createClientScopePage.save().checkClientNameRequiredMessage();
@ -102,7 +314,7 @@ describe("Client Scopes test", () => {
.deleteItem(itemId);
modalUtils
.checkModalMessage("Are you sure you want to delete this client scope")
.checkModalMessage(modalMessageDeleteConfirmation)
.confirmModal();
masthead.checkNotificationMessage("The client scope has been deleted");
@ -115,12 +327,6 @@ describe("Client Scopes test", () => {
const scopeTab = new RoleMappingTab();
const scopeName = "address";
beforeEach(() => {
keycloakBefore();
loginPage.logIn();
sidebarPage.goToClientScopes();
});
it("Assign role", () => {
const role = "offline_access";
listingPage.searchItem(scopeName, false).goToItemDetails(scopeName);

View file

@ -1,6 +1,9 @@
import LoginPage from "../support/pages/LoginPage";
import Masthead from "../support/pages/admin_console/Masthead";
import ListingPage from "../support/pages/admin_console/ListingPage";
import ListingPage, {
Filter,
FilterAssignedType,
} from "../support/pages/admin_console/ListingPage";
import SidebarPage from "../support/pages/admin_console/SidebarPage";
import CreateClientPage from "../support/pages/admin_console/manage/clients/CreateClientPage";
import ModalUtils from "../support/util/ModalUtils";
@ -25,10 +28,12 @@ const modalUtils = new ModalUtils();
describe("Clients test", () => {
describe("Client details - Client scopes subtab", () => {
const clientScopesTab = new ClientScopesTab();
const client = new AdminClient();
const clientScopesTab = new ClientScopesTab();
const clientId = "client-scopes-subtab-test";
const clientScopeName = "client-scope-test";
const clientScopeNameDefaultType = "client-scope-test-default-type";
const clientScopeNameOptionalType = "client-scope-test-optional-type";
const clientScope = {
name: clientScopeName,
description: "",
@ -40,6 +45,7 @@ describe("Clients test", () => {
"consent.screen.text": "",
},
};
const msgScopeMappingRemoved = "Scope mapping successfully removed";
before(async () => {
client.createClient({
@ -55,6 +61,10 @@ describe("Clients test", () => {
clientId
);
}
clientScope.name = clientScopeNameDefaultType;
await client.createClientScope(clientScope);
clientScope.name = clientScopeNameOptionalType;
await client.createClientScope(clientScope);
});
beforeEach(() => {
@ -72,12 +82,124 @@ describe("Clients test", () => {
for (let i = 0; i < 5; i++) {
await client.deleteClientScope(clientScopeName + i);
}
await client.deleteClientScope(clientScopeNameDefaultType);
await client.deleteClientScope(clientScopeNameOptionalType);
});
it("should list client scopes", () => {
listingPage.itemsGreaterThan(1).itemExist(clientScopeName + 0);
});
it("should search existing client scope by name", () => {
listingPage
.searchItem(clientScopeName + 0, false)
.itemExist(clientScopeName + 0)
.itemsEqualTo(2);
});
it("should search non-existent client scope by name", () => {
const itemName = "non-existent-item";
listingPage.searchItem(itemName, false).checkTableExists(false);
});
it("should search existing client scope by assigned type", () => {
listingPage
.selectFilter(Filter.AssignedType)
.selectSecondaryFilterAssignedType(FilterAssignedType.Default)
.itemExist(FilterAssignedType.Default)
.itemExist(FilterAssignedType.Optional, false)
.selectSecondaryFilterAssignedType(FilterAssignedType.Optional)
.itemExist(FilterAssignedType.Default, false)
.itemExist(FilterAssignedType.Optional)
.selectSecondaryFilterAssignedType(FilterAssignedType.AllTypes)
.itemExist(FilterAssignedType.Default)
.itemExist(FilterAssignedType.Optional);
});
/*it("should empty search", () => {
});*/
const newItemsWithExpectedAssignedTypes = [
[clientScopeNameOptionalType, FilterAssignedType.Optional],
[clientScopeNameDefaultType, FilterAssignedType.Default],
];
newItemsWithExpectedAssignedTypes.forEach(($type) => {
const [itemName, assignedType] = $type;
it(`should add client scope ${itemName} with ${assignedType} assigned type`, () => {
listingPage.clickPrimaryButton();
modalUtils.checkModalTitle("Add client scopes to " + clientId);
listingPage.clickItemCheckbox(itemName);
modalUtils.confirmModalWithItem(assignedType);
masthead.checkNotificationMessage("Scope mapping successfully updated");
listingPage
.searchItem(itemName, false)
.itemExist(itemName)
.itemExist(assignedType);
});
});
const expectedItemAssignedTypes = [
FilterAssignedType.Optional,
FilterAssignedType.Default,
];
expectedItemAssignedTypes.forEach(($assignedType) => {
const itemName = clientScopeName + 0;
it(`should change item ${itemName} AssignedType to ${$assignedType} from search bar`, () => {
listingPage
.searchItem(itemName, false)
.clickItemCheckbox(itemName)
.changeTypeToOfSelectedItems($assignedType);
masthead.checkNotificationMessage("Scope mapping updated");
listingPage.searchItem(itemName, false).itemExist($assignedType);
});
});
it("should show items on next page are more than 11", () => {
listingPage.showNextPageTableItems();
cy.get(listingPage.tableRowItem).its("length").should("be.gt", 1);
listingPage.showNextPageTableItems().itemsGreaterThan(1);
});
it("should remove client scope from item bar", () => {
const itemName = clientScopeName + 0;
listingPage.searchItem(itemName, false).removeItem(itemName);
masthead.checkNotificationMessage(msgScopeMappingRemoved);
listingPage.searchItem(itemName, false).checkTableExists(false);
});
/*it("should remove client scope from search bar", () => {
//covered by next test
});*/
// TODO: https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should remove multiple client scopes from search bar", () => {
const itemName1 = clientScopeName + 1;
const itemName2 = clientScopeName + 2;
listingPage
.clickSearchBarActionButton()
.checkDropdownItemIsDisabled("Remove")
.searchItem(clientScopeName, false)
.clickItemCheckbox(itemName1)
.clickItemCheckbox(itemName2)
.clickSearchBarActionButton()
.clickSearchBarActionItem("Remove");
masthead.checkNotificationMessage(msgScopeMappingRemoved);
listingPage
.searchItem(clientScopeName, false)
.itemExist(itemName1, false)
.itemExist(itemName2, false)
.clickSearchBarActionButton();
//.checkDropdownItemIsDisabled("Remove");
});
//TODO: https://github.com/keycloak/keycloak-admin-ui/issues/1874
/* it("should show initial items after filtering", () => {
listingPage
.selectFilter(Filter.AssignedType)
.selectFilterAssignedType(FilterAssignedType.Optional)
.selectFilter(Filter.Name)
.itemExist(FilterAssignedType.Default)
.itemExist(FilterAssignedType.Optional);
});*/
});
describe("Client creation", () => {

View file

@ -1,10 +1,41 @@
export enum Filter {
Name = "Name",
AssignedType = "Assigned type",
Protocol = "Protocol",
}
export enum FilterAssignedType {
AllTypes = "All types",
Default = "Default",
Optional = "Optional",
None = "None",
}
export enum FilterProtocol {
All = "All",
SAML = "SAML",
OpenID = "openid-connect", //TODO: text to be unified with item text
}
export enum FilterSession {
AllSessionTypes = "All session types",
RegularSSO = "Regular SSO",
Offline = "Offline",
DirectGrant = "Direct grant",
ServiceAccount = "Service account",
}
export default class ListingPage {
private searchInput = '.pf-c-toolbar__item [type="search"]:visible';
private tableToolbar = ".pf-c-toolbar";
private itemsRows = "table:visible";
private emptyListImg =
'[role="tabpanel"]:not([hidden]) [data-testid="empty-state"]';
private progressBar = '[role="progressbar"]';
private itemRowDrpDwn = ".pf-c-dropdown__toggle";
private itemRowSelect = ".pf-c-select__toggle:nth-child(1)";
private itemRowSelectItem = ".pf-c-select__menu-item";
private itemCheckbox = ".pf-c-table__check";
public exportBtn = '[role="menuitem"]:nth-child(1)';
public deleteBtn = '[role="menuitem"]:nth-child(2)';
private searchBtn =
@ -18,6 +49,12 @@ export default class ListingPage {
private nextPageBtn =
"div[class=pf-c-pagination__nav-control] button[data-action=next]:visible";
public tableRowItem = "tbody tr[data-ouia-component-type]:visible";
private table = "table[aria-label]";
private filterSessionDropdownButton = ".pf-c-select button:nth-child(1)";
private filterDropdownButton = "[class*='searchtype'] button";
private dropdownItem = ".pf-c-dropdown__menu-item";
private changeTypeToButton = ".pf-c-select__toggle";
private toolbarChangeType = "#change-type-dropdown";
showPreviousPageTableItems() {
cy.get(this.previousPageBtn).first().click();
@ -62,6 +99,21 @@ export default class ListingPage {
return this;
}
clickSearchBarActionButton() {
cy.get(this.tableToolbar).find(this.itemRowDrpDwn).last().click();
return this;
}
clickSearchBarActionItem(itemName: string) {
cy.get(this.tableToolbar)
.find(this.dropdownItem)
.contains(itemName)
.click();
return this;
}
clickRowDetails(itemName: string) {
cy.get(this.itemsRows)
.contains(itemName)
@ -99,6 +151,37 @@ export default class ListingPage {
return this;
}
clickItemCheckbox(itemName: string) {
cy.get(this.itemsRows)
.contains(itemName)
.parentsUntil("tbody")
.find(this.itemCheckbox)
.click();
return this;
}
clickRowSelectButton(itemName: string) {
cy.get(this.itemsRows)
.contains(itemName)
.parentsUntil("tbody")
.find(this.itemRowSelect)
.click();
return this;
}
clickPrimaryButton() {
cy.get(this.listHeaderPrimaryBtn).click();
return this;
}
clickRowSelectItem(rowItemName: string, selectItemName: string) {
this.clickRowSelectButton(rowItemName);
cy.get(this.itemRowSelectItem).contains(selectItemName).click();
return this;
}
itemExist(itemName: string, exist = true) {
cy.get(this.itemsRows)
.contains(itemName)
@ -132,4 +215,121 @@ export default class ListingPage {
return this;
}
removeItem(itemName: string) {
this.clickRowDetails(itemName);
this.clickDetailMenu("Remove");
return this;
}
itemsEqualTo(amount: number) {
cy.get(this.tableRowItem).its("length").should("be.eq", amount);
return this;
}
itemsGreaterThan(amount: number) {
cy.get(this.tableRowItem).its("length").should("be.gt", amount);
return this;
}
itemContainValue(itemName: string, colIndex: number, value: string) {
cy.get(this.itemsRows)
.contains(itemName)
.parentsUntil("tbody")
.find("td")
.eq(colIndex)
.should("contain", value);
return this;
}
selectFilter(filter: Filter) {
cy.get(this.filterDropdownButton).first().click();
cy.get(this.dropdownItem).contains(filter).click();
return this;
}
selectSecondaryFilter(itemName: string) {
cy.get(this.filterDropdownButton).last().click();
cy.get(this.itemRowSelectItem).contains(itemName).click();
return this;
}
selectSecondaryFilterAssignedType(assignedType: FilterAssignedType) {
this.selectSecondaryFilter(assignedType);
return this;
}
selectSecondaryFilterProtocol(protocol: FilterProtocol) {
this.selectSecondaryFilter(protocol);
return this;
}
selectSecondaryFilterSession(sessionName: FilterSession) {
cy.get(this.filterSessionDropdownButton).click();
cy.get(this.itemRowSelectItem).contains(sessionName);
return this;
}
changeTypeToOfSelectedItems(assignedType: FilterAssignedType) {
cy.intercept("/auth/admin/realms/master/client-scopes").as("load");
cy.get(this.toolbarChangeType).click();
cy.get(this.itemRowSelectItem).contains(assignedType).click();
cy.wait("@load");
return this;
}
changeTypeToOfItem(assignedType: FilterAssignedType, itemName: string) {
cy.get(this.itemsRows)
.contains(itemName)
.parentsUntil("tbody")
.find(this.changeTypeToButton)
.first()
.click();
cy.get(this.itemsRows)
.contains(itemName)
.parentsUntil("tbody")
.find(this.changeTypeToButton)
.contains(assignedType)
.click();
return this;
}
checkInSearchBarChangeTypeToButtonIsDisabled(disabled: boolean = true) {
let condition = "be.disabled";
if (!disabled) {
condition = "be.enabled";
}
cy.get(this.changeTypeToButton).first().should(condition);
return this;
}
checkDropdownItemIsDisabled(itemName: string, disabled: boolean = true) {
cy.get(this.dropdownItem)
.contains(itemName)
.should("have.attr", "aria-disabled", String(disabled));
return this;
}
checkTableExists(exists: boolean = true) {
let condition = "be.visible";
if (!exists) {
condition = "not.be.visible";
}
cy.get(this.table).should(condition);
return this;
}
}

View file

@ -113,6 +113,15 @@ export default class AdminClient {
return await this.client.clientScopes.del({ id: clientScope?.id! });
}
async existsClientScope(clientScopeName: string) {
await this.login();
return (await this.client.clientScopes.findOneByName({
name: clientScopeName,
})) == undefined
? false
: true;
}
async addDefaultClientScopeInClient(
clientScopeName: string,
clientId: string

View file

@ -6,6 +6,8 @@ export default class ModalUtils {
private cancelModalBtn = "cancel";
private closeModalBtn = ".pf-c-modal-box .pf-m-plain";
private copyToClipboardBtn = '[id*="copy-button"]';
private addModalDropdownBtn = "#add-dropdown > button";
private addModalDropdownItem = "#add-dropdown [role='menuitem']";
confirmModal() {
cy.findByTestId(this.confirmModalBtn).click({ force: true });
@ -19,6 +21,13 @@ export default class ModalUtils {
return this;
}
confirmModalWithItem(itemName: string) {
cy.get(this.addModalDropdownBtn).click();
cy.get(this.addModalDropdownItem).contains(itemName).click();
return this;
}
cancelModal() {
cy.findByTestId(this.cancelModalBtn).click({ force: true });

View file

@ -32,7 +32,7 @@ export const ChangeTypeDropdown = ({
return (
<Select
id="change-type-dropdown"
toggleId="change-type-dropdown"
isOpen={open}
selections={[]}
isDisabled={selectedRows.length === 0}

View file

@ -56,9 +56,6 @@ export default function ClientScopesSection() {
const adminClient = useAdminClient();
const { addAlert, addError } = useAlerts();
const [key, setKey] = useState(0);
const refresh = () => setKey(new Date().getTime());
const [kebabOpen, setKebabOpen] = useState(false);
const [selectedScopes, setSelectedScopes] = useState<
ClientScopeDefaultOptionalType[]
@ -70,6 +67,12 @@ export default function ClientScopesSection() {
);
const [searchProtocol, setSearchProtocol] = useState<ProtocolType>("all");
const [key, setKey] = useState(0);
const refresh = () => {
setSelectedScopes([]);
setKey(key + 1);
};
const loader = async (first?: number, max?: number, search?: string) => {
const defaultScopes =
await adminClient.clientScopes.listDefaultClientScopes();

View file

@ -75,7 +75,6 @@ export const ClientScopes = ({
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
const isDedicatedRow = (value: Row) => value.id === DEDICATED_ROW;
const loader = async (first?: number, max?: number, search?: string) => {