([]);
const { addAlert } = useAlerts();
- const membersLength = "membersLength";
+ const [key, setKey] = useState("");
+ const refresh = () => setKey(`${new Date().getTime()}`);
+
+ const getMembers = async (id: string) => {
+ const response = await adminClient.groups.listMembers({ id });
+ return response ? response.length : 0;
+ };
const loader = async () => {
const groupsData = await adminClient.groups.find();
- const getMembers = async (id: string) => {
- const response = await adminClient.groups.listMembers({ id });
- return response.length;
- };
-
- const memberPromises = groupsData.map((group: { [key: string]: any }) =>
- getMembers(group[columnID])
- );
+ const memberPromises = groupsData.map((group) => getMembers(group.id!));
const memberData = await Promise.all(memberPromises);
- const updatedObject = groupsData.map(
- (group: { [key: string]: any }, i: number) => {
- const object = Object.assign({}, group);
- object[membersLength] = memberData[i];
- return object;
- }
- );
- setFilteredData(updatedObject);
- setRawData(updatedObject);
- };
-
- useEffect(() => {
- loader();
- }, []);
-
- // Filter groups
- const filterGroups = (newInput: string) => {
- const localRowData = rawData!.filter((obj: { [key: string]: string }) => {
- const groupName = obj[columnGroupName];
- return groupName.toLowerCase().includes(newInput.toLowerCase());
+ const updatedObject = groupsData.map((group: GroupTableData, i) => {
+ group.membersLength = memberData[i];
+ return group;
});
- setFilteredData(localRowData);
- };
-
- // Kebab delete action
- const onKebabToggle = (isOpen: boolean) => {
- setIsKebabOpen(isOpen);
- };
-
- const onKebabSelect = () => {
- setIsKebabOpen(!isKebabOpen);
+ return updatedObject;
};
const handleModalToggle = () => {
setIsCreateModalOpen(!isCreateModalOpen);
};
- const multiDelete = async () => {
- if (tableRowSelectedArray.length !== 0) {
- const deleteGroup = async (rowId: number) => {
- try {
- await adminClient.groups.del({
- id: filteredData ? filteredData![rowId].id : rawData![rowId].id,
- });
- loader();
- } catch (error) {
- addAlert(`${t("groupDeleteError")} ${error}`, AlertVariant.danger);
- }
- };
-
- const chainedPromises = tableRowSelectedArray.map((rowId: number) => {
- deleteGroup(rowId);
+ const deleteGroup = (group: GroupRepresentation) => {
+ try {
+ return adminClient.groups.del({
+ id: group.id!,
});
-
- await Promise.all(chainedPromises)
- .then(() => addAlert(t("groupsDeleted"), AlertVariant.success))
- .then(() => setTableRowSelectedArray([]));
+ } catch (error) {
+ addAlert(t("groupDeleteError", { error }), AlertVariant.danger);
}
};
+ const multiDelete = async () => {
+ if (selectedRows!.length !== 0) {
+ const chainedPromises = selectedRows!.map((group) => deleteGroup(group));
+
+ await Promise.all(chainedPromises);
+ addAlert(t("groupsDeleted"), AlertVariant.success);
+ setSelectedRows([]);
+ refresh();
+ }
+ };
+
+ const GroupNameCell = (group: GroupTableData) => (
+ <>
+
+ {group.name}
+
+ >
+ );
+
+ const GroupMemberCell = (group: GroupTableData) => (
+
+
+ {group.membersLength}
+
+ );
+
return (
<>
- {!rawData && (
-
-
-
- )}
- {rawData && rawData.length > 0 ? (
- <>
-
-
-
-
-
- }
- isOpen={isKebabOpen}
- isPlain
- dropdownItems={[
- multiDelete()}
- >
- {t("common:Delete")}
- ,
- ]}
+ setSelectedRows([...rows])}
+ canSelectAll={false}
+ loader={loader}
+ ariaLabelKey="client-scopes:clientScopeList"
+ searchPlaceholderKey="client-scopes:searchFor"
+ toolbarItem={
+ <>
+
+
+
+
+ setIsKebabOpen(!isKebabOpen)}
/>
-
- >
- }
- >
- {rawData && (
- {
+ multiDelete();
+ setIsKebabOpen(false);
+ }}
+ >
+ {t("common:delete")}
+ ,
+ ]}
/>
- )}
- {filteredData && filteredData.length === 0 && (
-
- )}
-
- >
- ) : (
- handleModalToggle()}
- />
- )}
+
+ >
+ }
+ actions={[
+ {
+ title: t("moveTo"),
+ onRowClick: () => console.log("TO DO: Add move to functionality"),
+ },
+ {
+ title: t("common:delete"),
+ onRowClick: async (group: GroupRepresentation) => {
+ await deleteGroup(group);
+ return true;
+ },
+ },
+ ]}
+ columns={[
+ {
+ name: "name",
+ displayKey: "groups:groupName",
+ cellRenderer: GroupNameCell,
+ },
+ {
+ name: "members",
+ displayKey: "groups:members",
+ cellRenderer: GroupMemberCell,
+ },
+ ]}
+ emptyState={
+ handleModalToggle()}
+ />
+ }
+ />
+
>
diff --git a/src/groups/messages.json b/src/groups/messages.json
index 5649f86524..4c314934c0 100644
--- a/src/groups/messages.json
+++ b/src/groups/messages.json
@@ -19,7 +19,8 @@
"noSearchResultsInstructions": "Click on the search bar above to search for groups",
"noGroupsInThisRealm": "No groups in this realm",
"noGroupsInThisRealmInstructions": "You haven't created any groups in this realm. Create a group to get started.",
+ "groupDelete": "Group deleted",
"groupsDeleted": "Groups deleted",
- "groupDeleteError": "Error deleting group"
+ "groupDeleteError": "Error deleting group {error}"
}
}
diff --git a/src/groups/models/groups.ts b/src/groups/models/groups.ts
deleted file mode 100644
index 3a49f075a1..0000000000
--- a/src/groups/models/groups.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export interface GroupRepresentation {
- id?: string;
- name?: string;
- path?: string;
- attributes?: { [index: string]: string[] };
- realmRoles?: string[];
- clientRoles?: { [index: string]: string[] };
- subGroups?: GroupRepresentation[];
- access?: { [index: string]: boolean };
- groupNumber?: number;
- membersLength?: number;
- list?: [];
-}
diff --git a/src/groups/models/server-info.ts b/src/groups/models/server-info.ts
deleted file mode 100644
index ad5871db40..0000000000
--- a/src/groups/models/server-info.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export interface ServerGroupsRepresentation {
- id?: number;
- name?: string;
- path?: string;
- subGroups?: [];
-}
-
-// TO DO: Update this to represent the data that is returned
-export interface ServerGroupMembersRepresentation {
- data?: [];
-}
-
-export interface ServerGroupsArrayRepresentation {
- groups: { [index: string]: ServerGroupsRepresentation[] };
-}
diff --git a/src/realm/models/Realm.ts b/src/realm/models/Realm.ts
deleted file mode 100644
index 7515973f01..0000000000
--- a/src/realm/models/Realm.ts
+++ /dev/null
@@ -1,500 +0,0 @@
-import { ClientScopeRepresentation } from "../../client-scopes/models/client-scope";
-
-export interface RealmRepresentation {
- id: string;
- realm: string;
- displayName?: string;
- displayNameHtml?: string;
- notBefore?: number;
- defaultSignatureAlgorithm?: string;
- revokeRefreshToken?: boolean;
- refreshTokenMaxReuse?: number;
- accessTokenLifespan?: number;
- accessTokenLifespanForImplicitFlow?: number;
- ssoSessionIdleTimeout?: number;
- ssoSessionMaxLifespan?: number;
- ssoSessionIdleTimeoutRememberMe?: number;
- ssoSessionMaxLifespanRememberMe?: number;
- offlineSessionIdleTimeout?: number;
- offlineSessionMaxLifespanEnabled?: boolean;
- offlineSessionMaxLifespan?: number;
- clientSessionIdleTimeout?: number;
- clientSessionMaxLifespan?: number;
- clientOfflineSessionIdleTimeout?: number;
- clientOfflineSessionMaxLifespan?: number;
- accessCodeLifespan?: number;
- accessCodeLifespanUserAction?: number;
- accessCodeLifespanLogin?: number;
- actionTokenGeneratedByAdminLifespan?: number;
- actionTokenGeneratedByUserLifespan?: number;
- enabled?: boolean;
- sslRequired?: string;
- passwordCredentialGrantAllowed?: boolean;
- registrationAllowed?: boolean;
- registrationEmailAsUsername?: boolean;
- rememberMe?: boolean;
- verifyEmail?: boolean;
- loginWithEmailAllowed?: boolean;
- duplicateEmailsAllowed?: boolean;
- resetPasswordAllowed?: boolean;
- editUsernameAllowed?: boolean;
- bruteForceProtected?: boolean;
- permanentLockout?: boolean;
- maxFailureWaitSeconds?: number;
- minimumQuickLoginWaitSeconds?: number;
- waitIncrementSeconds?: number;
- quickLoginCheckMilliSeconds?: number;
- maxDeltaTimeSeconds?: number;
- failureFactor?: number;
- privateKey?: string;
- publicKey?: string;
- certificate?: string;
- codeSecret?: string;
- roles?: RolesRepresentation;
- groups?: GroupRepresentation[];
- defaultRoles?: string[];
- defaultGroups?: string[];
- requiredCredentials?: string[];
- passwordPolicy?: string;
- otpPolicyType?: string;
- otpPolicyAlgorithm?: string;
- otpPolicyInitialCounter?: number;
- otpPolicyDigits?: number;
- otpPolicyLookAheadWindow?: number;
- otpPolicyPeriod?: number;
- otpSupportedApplications?: string[];
- webAuthnPolicyRpEntityName?: string;
- webAuthnPolicySignatureAlgorithms?: string[];
- webAuthnPolicyRpId?: string;
- webAuthnPolicyAttestationConveyancePreference?: string;
- webAuthnPolicyAuthenticatorAttachment?: string;
- webAuthnPolicyRequireResidentKey?: string;
- webAuthnPolicyUserVerificationRequirement?: string;
- webAuthnPolicyCreateTimeout?: number;
- webAuthnPolicyAvoidSameAuthenticatorRegister?: boolean;
- webAuthnPolicyAcceptableAaguids?: string[];
- webAuthnPolicyPasswordlessRpEntityName?: string;
- webAuthnPolicyPasswordlessSignatureAlgorithms?: string[];
- webAuthnPolicyPasswordlessRpId?: string;
- webAuthnPolicyPasswordlessAttestationConveyancePreference?: string;
- webAuthnPolicyPasswordlessAuthenticatorAttachment?: string;
- webAuthnPolicyPasswordlessRequireResidentKey?: string;
- webAuthnPolicyPasswordlessUserVerificationRequirement?: string;
- webAuthnPolicyPasswordlessCreateTimeout?: number;
- webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister?: boolean;
- webAuthnPolicyPasswordlessAcceptableAaguids?: string[];
- users?: UserRepresentation[];
- federatedUsers?: UserRepresentation[];
- scopeMappings?: ScopeMappingRepresentation[];
- clientScopeMappings?: { [index: string]: ScopeMappingRepresentation[] };
- clients?: ClientRepresentation[];
- clientScopes?: ClientScopeRepresentation[];
- defaultDefaultClientScopes?: string[];
- defaultOptionalClientScopes?: string[];
- browserSecurityHeaders?: { [index: string]: string };
- smtpServe?: { [index: string]: string };
- userFederationProviders?: UserFederationProviderRepresentation[];
- userFederationMappers?: UserFederationMapperRepresentation[];
- loginTheme?: string;
- accountTheme?: string;
- adminTheme?: string;
- emailTheme?: string;
- eventsEnabled?: boolean;
- eventsExpiration?: number;
- eventsListeners?: string[];
- enabledEventTypes?: string[];
- adminEventsEnabled?: boolean;
- adminEventsDetailsEnabled?: boolean;
- identityProviders?: IdentityProviderRepresentation[];
- identityProviderMappers?: IdentityProviderMapperRepresentation[];
- protocolMappers?: ProtocolMapperRepresentation[];
- components?: { [index: string]: ComponentExportRepresentation };
- internationalizationEnabled?: boolean;
- supportedLocales?: string[];
- defaultLocale?: string;
- authenticationFlows?: AuthenticationFlowRepresentation[];
- authenticatorConfig?: AuthenticatorConfigRepresentation[];
- requiredActions?: RequiredActionProviderRepresentation[];
- browserFlow?: string;
- registrationFlow?: string;
- directGrantFlow?: string;
- resetCredentialsFlow?: string;
- clientAuthenticationFlow?: string;
- dockerAuthenticationFlow?: string;
- attributes?: { [index: string]: string };
- keycloakVersion?: string;
- userManagedAccessAllowed?: boolean;
- social?: boolean;
- updateProfileOnInitialSocialLogin?: boolean;
- socialProviders?: { [index: string]: string };
- applicationScopeMappings?: { [index: string]: ScopeMappingRepresentation[] };
- applications?: ApplicationRepresentation[];
- oauthClients?: OAuthClientRepresentation[];
- clientTemplates?: ClientTemplateRepresentation[];
-}
-
-export interface RolesRepresentation {
- realm: RoleRepresentation[];
- client: { [index: string]: RoleRepresentation[] };
- application: { [index: string]: RoleRepresentation[] };
-}
-
-export interface GroupRepresentation {
- id: string;
- name: string;
- path: string;
- attributes: { [index: string]: string[] };
- realmRoles: string[];
- clientRoles: { [index: string]: string[] };
- subGroups: GroupRepresentation[];
- access: { [index: string]: boolean };
-}
-
-export interface UserRepresentation {
- self: string;
- id: string;
- origin: string;
- createdTimestamp: number;
- username: string;
- enabled: boolean;
- totp: boolean;
- emailVerified: boolean;
- firstName: string;
- lastName: string;
- email: string;
- federationLink: string;
- serviceAccountClientId: string;
- attributes: { [index: string]: string[] };
- credentials: CredentialRepresentation[];
- disableableCredentialTypes: string[];
- requiredActions: string[];
- federatedIdentities: FederatedIdentityRepresentation[];
- realmRoles: string[];
- clientRoles: { [index: string]: string[] };
- clientConsents: UserConsentRepresentation[];
- notBefore: number;
- applicationRoles: { [index: string]: string[] };
- socialLinks: SocialLinkRepresentation[];
- groups: string[];
- access: { [index: string]: boolean };
-}
-
-export interface ScopeMappingRepresentation {
- self: string;
- client: string;
- clientTemplate: string;
- clientScope: string;
- roles: string[];
-}
-
-export interface ClientRepresentation {
- id: string;
- clientId: string;
- name: string;
- description: string;
- rootUrl: string;
- adminUrl: string;
- baseUrl: string;
- surrogateAuthRequired: boolean;
- enabled: boolean;
- alwaysDisplayInConsole: boolean;
- clientAuthenticatorType: string;
- secret: string;
- registrationAccessToken: string;
- defaultRoles: string[];
- redirectUris: string[];
- webOrigins: string[];
- notBefore: number;
- bearerOnly: boolean;
- consentRequired: boolean;
- standardFlowEnabled: boolean;
- implicitFlowEnabled: boolean;
- directAccessGrantsEnabled: boolean;
- serviceAccountsEnabled: boolean;
- authorizationServicesEnabled: boolean;
- directGrantsOnly: boolean;
- publicClient: boolean;
- frontchannelLogout: boolean;
- protocol: string;
- attributes: { [index: string]: string };
- authenticationFlowBindingOverrides: { [index: string]: string };
- fullScopeAllowed: boolean;
- nodeReRegistrationTimeout: number;
- registeredNodes: { [index: string]: number };
- protocolMappers: ProtocolMapperRepresentation[];
- clientTemplate: string;
- useTemplateConfig: boolean;
- useTemplateScope: boolean;
- useTemplateMappers: boolean;
- defaultClientScopes: string[];
- optionalClientScopes: string[];
- authorizationSettings: ResourceServerRepresentation;
- access: { [index: string]: boolean };
- origin: string;
-}
-
-export interface UserFederationProviderRepresentation {
- id: string;
- displayName: string;
- providerName: string;
- config: { [index: string]: string };
- priority: number;
- fullSyncPeriod: number;
- changedSyncPeriod: number;
- lastSync: number;
-}
-
-export interface UserFederationMapperRepresentation {
- id: string;
- name: string;
- federationProviderDisplayName: string;
- federationMapperType: string;
- config: { [index: string]: string };
-}
-
-export interface IdentityProviderRepresentation {
- alias: string;
- displayName: string;
- internalId: string;
- providerId: string;
- enabled: boolean;
- updateProfileFirstLoginMode: string;
- trustEmail: boolean;
- storeToken: boolean;
- addReadTokenRoleOnCreate: boolean;
- authenticateByDefault: boolean;
- linkOnly: boolean;
- firstBrokerLoginFlowAlias: string;
- postBrokerLoginFlowAlias: string;
- config: { [index: string]: string };
-}
-
-export interface IdentityProviderMapperRepresentation {
- id: string;
- name: string;
- identityProviderAlias: string;
- identityProviderMapper: string;
- config: { [index: string]: string };
-}
-
-export interface ProtocolMapperRepresentation {
- id: string;
- name: string;
- protocol: string;
- protocolMapper: string;
- consentRequired: boolean;
- consentText: string;
- config: { [index: string]: string };
-}
-
-export interface ComponentExportRepresentation {
- id: string;
- name: string;
- providerId: string;
- subType: string;
- subComponents: { [index: string]: ComponentExportRepresentation };
- config: { [index: string]: string };
-}
-
-export interface AuthenticationFlowRepresentation extends Serializable {
- id: string;
- alias: string;
- description: string;
- providerId: string;
- topLevel: boolean;
- builtIn: boolean;
- authenticationExecutions: AuthenticationExecutionExportRepresentation[];
-}
-
-export interface AuthenticatorConfigRepresentation extends Serializable {
- id: string;
- alias: string;
- config: { [index: string]: string };
-}
-
-export interface RequiredActionProviderRepresentation {
- alias: string;
- name: string;
- providerId: string;
- enabled: boolean;
- defaultAction: boolean;
- priority: number;
- config: { [index: string]: string };
-}
-
-export interface ApplicationRepresentation extends ClientRepresentation {
- claims: ClaimRepresentation;
-}
-
-export interface OAuthClientRepresentation extends ApplicationRepresentation {}
-
-export interface ClientTemplateRepresentation {
- id: string;
- name: string;
- description: string;
- protocol: string;
- fullScopeAllowed: boolean;
- bearerOnly: boolean;
- consentRequired: boolean;
- standardFlowEnabled: boolean;
- implicitFlowEnabled: boolean;
- directAccessGrantsEnabled: boolean;
- serviceAccountsEnabled: boolean;
- publicClient: boolean;
- frontchannelLogout: boolean;
- attributes: { [index: string]: string };
- protocolMappers: ProtocolMapperRepresentation[];
-}
-
-export interface RoleRepresentation {
- id: string;
- name: string;
- description: string;
- scopeParamRequired: boolean;
- composite: boolean;
- composites: Composites;
- clientRole: boolean;
- containerId: string;
- attributes: { [index: string]: string[] };
-}
-
-export interface CredentialRepresentation {
- id: string;
- type: string;
- userLabel: string;
- createdDate: number;
- secretData: string;
- credentialData: string;
- priority: number;
- value: string;
- temporary: boolean;
- device: string;
- hashedSaltedValue: string;
- salt: string;
- hashIterations: number;
- counter: number;
- algorithm: string;
- digits: number;
- period: number;
- config: { [index: string]: string };
-}
-
-export interface FederatedIdentityRepresentation {
- identityProvider: string;
- userId: string;
- userName: string;
-}
-
-export interface UserConsentRepresentation {
- clientId: string;
- grantedClientScopes: string[];
- createdDate: number;
- lastUpdatedDate: number;
- grantedRealmRoles: string[];
-}
-
-export interface SocialLinkRepresentation {
- socialProvider: string;
- socialUserId: string;
- socialUsername: string;
-}
-
-export interface ResourceServerRepresentation {
- id: string;
- clientId: string;
- name: string;
- allowRemoteResourceManagement: boolean;
- policyEnforcementMode: PolicyEnforcementMode;
- resources: ResourceRepresentation[];
- policies: PolicyRepresentation[];
- scopes: ScopeRepresentation[];
- decisionStrategy: DecisionStrategy;
-}
-
-export interface AuthenticationExecutionExportRepresentation
- extends AbstractAuthenticationExecutionRepresentation {
- flowAlias: string;
- userSetupAllowed: boolean;
-}
-
-export interface Serializable {}
-
-export interface ClaimRepresentation {
- name: boolean;
- username: boolean;
- profile: boolean;
- picture: boolean;
- website: boolean;
- email: boolean;
- gender: boolean;
- locale: boolean;
- address: boolean;
- phone: boolean;
-}
-
-export interface Composites {
- realm: string[];
- client: { [index: string]: string[] };
- application: { [index: string]: string[] };
-}
-
-export interface ResourceRepresentation {
- name: string;
- type: string;
- owner: ResourceOwnerRepresentation;
- ownerManagedAccess: boolean;
- displayName: string;
- attributes: { [index: string]: string[] };
- _id: string;
- uris: string[];
- scopes: ScopeRepresentation[];
- icon_uri: string;
-}
-
-export interface PolicyRepresentation extends AbstractPolicyRepresentation {
- config: { [index: string]: string };
-}
-
-export interface ScopeRepresentation {
- id: string;
- name: string;
- iconUri: string;
- policies: PolicyRepresentation[];
- resources: ResourceRepresentation[];
- displayName: string;
-}
-
-export interface AbstractAuthenticationExecutionRepresentation
- extends Serializable {
- authenticatorConfig: string;
- authenticator: string;
- requirement: string;
- priority: number;
- autheticatorFlow: boolean;
-}
-
-export interface ResourceOwnerRepresentation {
- id: string;
- name: string;
-}
-
-export interface AbstractPolicyRepresentation {
- id: string;
- name: string;
- description: string;
- type: string;
- policies: string[];
- resources: string[];
- scopes: string[];
- logic: Logic;
- decisionStrategy: DecisionStrategy;
- owner: string;
- resourcesData: ResourceRepresentation[];
- scopesData: ScopeRepresentation[];
-}
-
-export type PolicyEnforcementMode = "ENFORCING" | "PERMISSIVE" | "DISABLED";
-
-export type DecisionStrategy = "AFFIRMATIVE" | "UNANIMOUS" | "CONSENSUS";
-
-export type Logic = "POSITIVE" | "NEGATIVE";