mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-16 14:50:15 +08:00
Merge remote-tracking branch 'origin/CB-2406-projects-permission-managment' into CB-2406-projects-permission-managment
This commit is contained in:
@@ -8,9 +8,10 @@
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { SessionDataResource } from '@cloudbeaver/core-root';
|
||||
import { GraphQLService, AdminPermissionInfo, CachedMapResource, CachedMapAllKey } from '@cloudbeaver/core-sdk';
|
||||
import { GraphQLService, CachedMapResource, CachedMapAllKey, AdminPermissionInfoFragment, AdminObjectGrantInfoFragment } from '@cloudbeaver/core-sdk';
|
||||
|
||||
export type PermissionInfo = AdminPermissionInfo;
|
||||
export type PermissionInfo = AdminPermissionInfoFragment;
|
||||
export type AdminObjectGrantInfo = AdminObjectGrantInfoFragment;
|
||||
|
||||
@injectable()
|
||||
export class PermissionsResource extends CachedMapResource<string, PermissionInfo> {
|
||||
|
||||
@@ -109,6 +109,7 @@ export const Button = observer<ButtonProps>(function Button({
|
||||
mod,
|
||||
styles,
|
||||
tag = 'button',
|
||||
type = 'button',
|
||||
disabled = false,
|
||||
loading,
|
||||
loader,
|
||||
@@ -143,7 +144,14 @@ export const Button = observer<ButtonProps>(function Button({
|
||||
|
||||
const Button = tag;
|
||||
return styled(useStyles(styles, buttonStyles, ...(mod || []).map(mod => buttonMod[mod])))(
|
||||
<Button {...rest} disabled={disabled} {...use({ loading })} className={className} onClick={state.click}>
|
||||
<Button
|
||||
{...rest}
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
{...use({ loading })}
|
||||
className={className}
|
||||
onClick={state.click}
|
||||
>
|
||||
<ripple />
|
||||
{icon && <button-icon><Icon name={icon} viewBox={viewBox} /></button-icon>}
|
||||
<button-label as='span'>{children}</button-label>
|
||||
|
||||
@@ -55,7 +55,7 @@ export const StatusMessage = observer<Props>(function StatusMessage({
|
||||
}) {
|
||||
const translate = useTranslate();
|
||||
const errorDetails = useErrorDetails(exception);
|
||||
message = (message ? translate(message) : message) ?? errorDetails.details?.name;
|
||||
message = (message ? translate(message) : message) ?? errorDetails.details?.message;
|
||||
let icon = '/icons/info_icon.svg';
|
||||
|
||||
if (status === ENotificationType.Error || exception !== null) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export function getSelectedItems(items: Map<any, boolean>): any[] {
|
||||
const result: any[] = [];
|
||||
export function getSelectedItems<T>(items: Map<T, boolean>): T[] {
|
||||
const result: T[] = [];
|
||||
|
||||
for (const [key, value] of items) {
|
||||
if (value) {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { PermissionInfo } from '@cloudbeaver/core-administration';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { ServerConfigResource } from '@cloudbeaver/core-root';
|
||||
import { GraphQLService, CachedDataResource } from '@cloudbeaver/core-sdk';
|
||||
|
||||
@injectable()
|
||||
export class SharedProjectPermissionsResource extends CachedDataResource<PermissionInfo[], void | any> {
|
||||
constructor(
|
||||
private readonly graphQLService: GraphQLService,
|
||||
serverConfigResource: ServerConfigResource
|
||||
) {
|
||||
super([]);
|
||||
|
||||
this.sync(serverConfigResource, () => {}, () => {});
|
||||
}
|
||||
|
||||
protected async loader(): Promise<PermissionInfo[]> {
|
||||
const { permissions } = await this.graphQLService.sdk.getProjectPermissionsList();
|
||||
|
||||
return permissions as any as PermissionInfo[];
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,16 @@
|
||||
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
import { EAdminPermission } from '@cloudbeaver/core-administration';
|
||||
import { AdminObjectGrantInfo, EAdminPermission } from '@cloudbeaver/core-administration';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { SessionPermissionsResource } from '@cloudbeaver/core-root';
|
||||
import { GraphQLService, CachedMapResource, CachedMapAllKey, ResourceKey, ResourceKeyUtils, resourceKeyList, RmProject, ResourceKeyList } from '@cloudbeaver/core-sdk';
|
||||
import { GraphQLService, CachedMapResource, CachedMapAllKey, ResourceKey, ResourceKeyUtils, resourceKeyList, RmProject, ResourceKeyList, AdminSubjectType, RmProjectPermissions } from '@cloudbeaver/core-sdk';
|
||||
import { isArraysEqual } from '@cloudbeaver/core-utils';
|
||||
|
||||
const newSymbol = Symbol('new-project');
|
||||
|
||||
export type SharedProject = RmProject;
|
||||
export type ProjectPermission = RmProjectPermissions;
|
||||
type SharedProjectNew = SharedProject & { [newSymbol]: boolean };
|
||||
|
||||
interface IProjectConfig {
|
||||
@@ -44,6 +46,21 @@ export class SharedProjectsResource extends CachedMapResource<string, SharedProj
|
||||
return newSymbol in this.get(id)!;
|
||||
}
|
||||
|
||||
async setAccessSubjects(projectId: string, permissions: ProjectPermission[]): Promise<void> {
|
||||
await this.graphQLService.sdk.setProjectPermissions({
|
||||
projectId,
|
||||
permissions,
|
||||
});
|
||||
}
|
||||
|
||||
async loadAccessSubjects(projectId: string): Promise<AdminObjectGrantInfo[]> {
|
||||
const { grantedPermissions } = await this.graphQLService.sdk.getProjectGrantedPermissions({
|
||||
projectId,
|
||||
});
|
||||
|
||||
return grantedPermissions;
|
||||
}
|
||||
|
||||
async create(config: IProjectConfig): Promise<SharedProject> {
|
||||
const { project } = await this.graphQLService.sdk.createProject({
|
||||
projectId: config.id,
|
||||
@@ -108,4 +125,13 @@ export class SharedProjectsResource extends CachedMapResource<string, SharedProj
|
||||
const data = this.data.get(key);
|
||||
this.data.set(key, Object.assign(data ?? {}, value));
|
||||
}
|
||||
}
|
||||
|
||||
export function isEqualSharedProjectGrantInfo(a: AdminObjectGrantInfo, b: AdminObjectGrantInfo): boolean {
|
||||
return (
|
||||
a.subjectId === b.subjectId
|
||||
&& a.subjectType === b.subjectType
|
||||
&& a.objectPermissions.objectId === b.objectPermissions.objectId
|
||||
&& isArraysEqual(a.objectPermissions.permissions, b.objectPermissions.permissions)
|
||||
);
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './SharedProjectsResource';
|
||||
export * from './SharedProjectPermissionsResource';
|
||||
export { resourceManagerManifest } from './manifest';
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import type { PluginManifest } from '@cloudbeaver/core-di';
|
||||
|
||||
import { SharedProjectPermissionsResource } from './SharedProjectPermissionsResource';
|
||||
import { SharedProjectsResource } from './SharedProjectsResource';
|
||||
|
||||
|
||||
@@ -18,5 +19,6 @@ export const resourceManagerManifest: PluginManifest = {
|
||||
|
||||
providers: [
|
||||
SharedProjectsResource,
|
||||
SharedProjectPermissionsResource,
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fragment AdminObjectGrantInfo on AdminObjectGrantInfo {
|
||||
subjectId
|
||||
subjectType
|
||||
objectPermissions {
|
||||
objectId
|
||||
permissions
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ query getProjectList {
|
||||
id
|
||||
name
|
||||
description
|
||||
canCreateConnections
|
||||
canViewConnections
|
||||
canEditDataSources
|
||||
canViewDataSources
|
||||
canEditResources
|
||||
canViewResources
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
query getProjectGrantedPermissions(
|
||||
$projectId: String!
|
||||
) {
|
||||
grantedPermissions: rmListProjectGrantedPermissions(
|
||||
projectId: $projectId
|
||||
) {
|
||||
...AdminObjectGrantInfo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query getProjectPermissionsList {
|
||||
permissions: rmListProjectPermissions {
|
||||
...AdminPermissionInfo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
mutation setProjectPermissions(
|
||||
$projectId: String!
|
||||
$permissions: [RMProjectPermissions!]!
|
||||
) {
|
||||
rmSetProjectPermissions(
|
||||
projectId: $projectId
|
||||
permissions: $permissions
|
||||
)
|
||||
}
|
||||
@@ -47,6 +47,17 @@ export interface AdminConnectionSearchInfo {
|
||||
possibleDrivers: Array<Scalars['ID']>;
|
||||
}
|
||||
|
||||
export interface AdminObjectGrantInfo {
|
||||
objectPermissions: AdminObjectPermissions;
|
||||
subjectId: Scalars['ID'];
|
||||
subjectType: AdminSubjectType;
|
||||
}
|
||||
|
||||
export interface AdminObjectPermissions {
|
||||
objectId: Scalars['ID'];
|
||||
permissions: Array<Scalars['String']>;
|
||||
}
|
||||
|
||||
export interface AdminPermissionInfo {
|
||||
category?: Maybe<Scalars['String']>;
|
||||
description?: Maybe<Scalars['String']>;
|
||||
@@ -371,6 +382,7 @@ export interface Mutation {
|
||||
rmDeleteProject: Scalars['Boolean'];
|
||||
rmDeleteResource?: Maybe<Scalars['Boolean']>;
|
||||
rmMoveResource: Scalars['String'];
|
||||
rmSetProjectPermissions: Scalars['Boolean'];
|
||||
rmWriteResourceStringContent: Scalars['String'];
|
||||
setConnectionNavigatorSettings: ConnectionInfo;
|
||||
setUserConfigurationParameter: Scalars['Boolean'];
|
||||
@@ -563,6 +575,12 @@ export interface MutationRmMoveResourceArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface MutationRmSetProjectPermissionsArgs {
|
||||
permissions: Array<RmProjectPermissions>;
|
||||
projectId: Scalars['String'];
|
||||
}
|
||||
|
||||
|
||||
export interface MutationRmWriteResourceStringContentArgs {
|
||||
data: Scalars['String'];
|
||||
forceOverwrite: Scalars['Boolean'];
|
||||
@@ -807,8 +825,10 @@ export interface ProductInfo {
|
||||
}
|
||||
|
||||
export interface ProjectInfo {
|
||||
canCreateConnections: Scalars['Boolean'];
|
||||
canViewConnections: Scalars['Boolean'];
|
||||
canEditDataSources: Scalars['Boolean'];
|
||||
canEditResources: Scalars['Boolean'];
|
||||
canViewDataSources: Scalars['Boolean'];
|
||||
canViewResources: Scalars['Boolean'];
|
||||
description?: Maybe<Scalars['String']>;
|
||||
id: Scalars['String'];
|
||||
name: Scalars['String'];
|
||||
@@ -861,9 +881,12 @@ export interface Query {
|
||||
networkHandlers: Array<NetworkHandlerDescriptor>;
|
||||
readSessionLog: Array<LogEntry>;
|
||||
revokeUserRole?: Maybe<Scalars['Boolean']>;
|
||||
rmListProjectGrantedPermissions: Array<AdminObjectGrantInfo>;
|
||||
rmListProjectPermissions?: Maybe<AdminPermissionInfo>;
|
||||
rmListProjects: Array<RmProject>;
|
||||
rmListResources: Array<RmResource>;
|
||||
rmListSharedProjects: Array<RmProject>;
|
||||
rmListSubjectProjectsPermissionGrants: Array<AdminObjectGrantInfo>;
|
||||
rmProject: RmProject;
|
||||
rmReadResourceAsString: Scalars['String'];
|
||||
saveAuthProviderConfiguration: AdminAuthProviderConfiguration;
|
||||
@@ -1109,6 +1132,11 @@ export interface QueryRevokeUserRoleArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryRmListProjectGrantedPermissionsArgs {
|
||||
projectId: Scalars['String'];
|
||||
}
|
||||
|
||||
|
||||
export interface QueryRmListResourcesArgs {
|
||||
folder?: InputMaybe<Scalars['String']>;
|
||||
nameMask?: InputMaybe<Scalars['String']>;
|
||||
@@ -1118,6 +1146,11 @@ export interface QueryRmListResourcesArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryRmListSubjectProjectsPermissionGrantsArgs {
|
||||
subjectId: Scalars['String'];
|
||||
}
|
||||
|
||||
|
||||
export interface QueryRmProjectArgs {
|
||||
projectId: Scalars['String'];
|
||||
}
|
||||
@@ -1291,6 +1324,11 @@ export interface RmProject {
|
||||
shared: Scalars['Boolean'];
|
||||
}
|
||||
|
||||
export interface RmProjectPermissions {
|
||||
permissions: Array<Scalars['String']>;
|
||||
subjectId: Scalars['String'];
|
||||
}
|
||||
|
||||
export interface RmResource {
|
||||
folder: Scalars['Boolean'];
|
||||
length: Scalars['Int'];
|
||||
@@ -2163,6 +2201,8 @@ export type NavGetStructContainersQueryVariables = Exact<{
|
||||
|
||||
export type NavGetStructContainersQuery = { navGetStructContainers: { supportsCatalogChange: boolean, supportsSchemaChange: boolean, catalogList: Array<{ catalog: { id: string, name?: string, hasChildren?: boolean, nodeType?: string, icon?: string, folder?: boolean, inline?: boolean, navigable?: boolean, features?: Array<string>, object?: { features?: Array<string> }, nodeDetails?: Array<{ id?: string, category?: string, dataType?: string, description?: string, displayName?: string, length: ObjectPropertyLength, features: Array<string>, value?: any, order: number }> }, schemaList: Array<{ id: string, name?: string, hasChildren?: boolean, nodeType?: string, icon?: string, folder?: boolean, inline?: boolean, navigable?: boolean, features?: Array<string>, object?: { features?: Array<string> }, nodeDetails?: Array<{ id?: string, category?: string, dataType?: string, description?: string, displayName?: string, length: ObjectPropertyLength, features: Array<string>, value?: any, order: number }> }> }>, schemaList: Array<{ id: string, name?: string, hasChildren?: boolean, nodeType?: string, icon?: string, folder?: boolean, inline?: boolean, navigable?: boolean, features?: Array<string>, object?: { features?: Array<string> }, nodeDetails?: Array<{ id?: string, category?: string, dataType?: string, description?: string, displayName?: string, length: ObjectPropertyLength, features: Array<string>, value?: any, order: number }> }> } };
|
||||
|
||||
export type AdminObjectGrantInfoFragment = { subjectId: string, subjectType: AdminSubjectType, objectPermissions: { objectId: string, permissions: Array<string> } };
|
||||
|
||||
export type AdminPermissionInfoFragment = { id: string, label?: string, description?: string, category?: string };
|
||||
|
||||
export type AdminRoleInfoFragment = { roleId: string, roleName?: string, description?: string, rolePermissions: Array<string> };
|
||||
@@ -2401,7 +2441,7 @@ export type NavRenameNodeMutation = { navRenameNode?: string };
|
||||
export type GetProjectListQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetProjectListQuery = { projects: Array<{ id: string, name: string, description?: string, canCreateConnections: boolean, canViewConnections: boolean }> };
|
||||
export type GetProjectListQuery = { projects: Array<{ id: string, name: string, description?: string, canEditDataSources: boolean, canViewDataSources: boolean, canEditResources: boolean, canViewResources: boolean }> };
|
||||
|
||||
export type CreateProjectMutationVariables = Exact<{
|
||||
projectId?: InputMaybe<Scalars['ID']>;
|
||||
@@ -2444,6 +2484,18 @@ export type GetProjectQueryVariables = Exact<{
|
||||
|
||||
export type GetProjectQuery = { project: { id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> } };
|
||||
|
||||
export type GetProjectGrantedPermissionsQueryVariables = Exact<{
|
||||
projectId: Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetProjectGrantedPermissionsQuery = { grantedPermissions: Array<{ subjectId: string, subjectType: AdminSubjectType, objectPermissions: { objectId: string, permissions: Array<string> } }> };
|
||||
|
||||
export type GetProjectPermissionsListQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetProjectPermissionsListQuery = { permissions?: { id: string, label?: string, description?: string, category?: string } };
|
||||
|
||||
export type GetResourceListQueryVariables = Exact<{
|
||||
projectId: Scalars['String'];
|
||||
folder?: InputMaybe<Scalars['String']>;
|
||||
@@ -2482,6 +2534,14 @@ export type ReadResourceQueryVariables = Exact<{
|
||||
|
||||
export type ReadResourceQuery = { value: string };
|
||||
|
||||
export type SetProjectPermissionsMutationVariables = Exact<{
|
||||
projectId: Scalars['String'];
|
||||
permissions: Array<RmProjectPermissions> | RmProjectPermissions;
|
||||
}>;
|
||||
|
||||
|
||||
export type SetProjectPermissionsMutation = { rmSetProjectPermissions: boolean };
|
||||
|
||||
export type WriteResourceContentMutationVariables = Exact<{
|
||||
projectId: Scalars['String'];
|
||||
resourcePath: Scalars['String'];
|
||||
@@ -2614,6 +2674,16 @@ export type SqlGenerateEntityQueryQueryVariables = Exact<{
|
||||
|
||||
export type SqlGenerateEntityQueryQuery = { sqlGenerateEntityQuery: string };
|
||||
|
||||
export const AdminObjectGrantInfoFragmentDoc = `
|
||||
fragment AdminObjectGrantInfo on AdminObjectGrantInfo {
|
||||
subjectId
|
||||
subjectType
|
||||
objectPermissions {
|
||||
objectId
|
||||
permissions
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AdminPermissionInfoFragmentDoc = `
|
||||
fragment AdminPermissionInfo on AdminPermissionInfo {
|
||||
id
|
||||
@@ -3890,8 +3960,10 @@ export const GetProjectListDocument = `
|
||||
id
|
||||
name
|
||||
description
|
||||
canCreateConnections
|
||||
canViewConnections
|
||||
canEditDataSources
|
||||
canViewDataSources
|
||||
canEditResources
|
||||
canViewResources
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -3936,6 +4008,20 @@ export const GetProjectDocument = `
|
||||
}
|
||||
}
|
||||
${SharedProjectFragmentDoc}`;
|
||||
export const GetProjectGrantedPermissionsDocument = `
|
||||
query getProjectGrantedPermissions($projectId: String!) {
|
||||
grantedPermissions: rmListProjectGrantedPermissions(projectId: $projectId) {
|
||||
...AdminObjectGrantInfo
|
||||
}
|
||||
}
|
||||
${AdminObjectGrantInfoFragmentDoc}`;
|
||||
export const GetProjectPermissionsListDocument = `
|
||||
query getProjectPermissionsList {
|
||||
permissions: rmListProjectPermissions {
|
||||
...AdminPermissionInfo
|
||||
}
|
||||
}
|
||||
${AdminPermissionInfoFragmentDoc}`;
|
||||
export const GetResourceListDocument = `
|
||||
query getResourceList($projectId: String!, $folder: String, $nameMask: String, $readProperties: Boolean, $readHistory: Boolean) {
|
||||
resources: rmListResources(
|
||||
@@ -3986,6 +4072,11 @@ export const ReadResourceDocument = `
|
||||
)
|
||||
}
|
||||
`;
|
||||
export const SetProjectPermissionsDocument = `
|
||||
mutation setProjectPermissions($projectId: String!, $permissions: [RMProjectPermissions!]!) {
|
||||
rmSetProjectPermissions(projectId: $projectId, permissions: $permissions)
|
||||
}
|
||||
`;
|
||||
export const WriteResourceContentDocument = `
|
||||
mutation writeResourceContent($projectId: String!, $resourcePath: String!, $data: String!, $forceOverwrite: Boolean!) {
|
||||
rmWriteResourceStringContent(
|
||||
@@ -4494,6 +4585,12 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
getProject(variables: GetProjectQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetProjectQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetProjectQuery>(GetProjectDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getProject', 'query');
|
||||
},
|
||||
getProjectGrantedPermissions(variables: GetProjectGrantedPermissionsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetProjectGrantedPermissionsQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetProjectGrantedPermissionsQuery>(GetProjectGrantedPermissionsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getProjectGrantedPermissions', 'query');
|
||||
},
|
||||
getProjectPermissionsList(variables?: GetProjectPermissionsListQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetProjectPermissionsListQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetProjectPermissionsListQuery>(GetProjectPermissionsListDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getProjectPermissionsList', 'query');
|
||||
},
|
||||
getResourceList(variables: GetResourceListQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetResourceListQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetResourceListQuery>(GetResourceListDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getResourceList', 'query');
|
||||
},
|
||||
@@ -4509,6 +4606,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
readResource(variables: ReadResourceQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<ReadResourceQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<ReadResourceQuery>(ReadResourceDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'readResource', 'query');
|
||||
},
|
||||
setProjectPermissions(variables: SetProjectPermissionsMutationVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<SetProjectPermissionsMutation> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<SetProjectPermissionsMutation>(SetProjectPermissionsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'setProjectPermissions', 'mutation');
|
||||
},
|
||||
writeResourceContent(variables: WriteResourceContentMutationVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<WriteResourceContentMutation> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<WriteResourceContentMutation>(WriteResourceContentDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'writeResourceContent', 'mutation');
|
||||
},
|
||||
|
||||
@@ -28,4 +28,8 @@ describe('Is array equals', () => {
|
||||
test('should return "false" when arrays length is different and the second array is larger', () => {
|
||||
expect(isArraysEqual([1, true], [1, true, '1'])).toBe(false);
|
||||
});
|
||||
|
||||
test('should use isEqual argument if passed', () => {
|
||||
expect(isArraysEqual([{ a:1 }], [{ a: 1 }], (a, b) => a.a === b.a)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -6,10 +6,16 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export function isArraysEqual<T>(first: T[], second: T[]): boolean {
|
||||
const isObjectEqual = <T>(a: T, b: T) => a === b;
|
||||
|
||||
export function isArraysEqual<T>(
|
||||
first: T[],
|
||||
second: T[],
|
||||
isEqual: (a: T, b: T) => boolean = isObjectEqual
|
||||
): boolean {
|
||||
if (first.length !== second.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !first.some(value => !second.includes(value));
|
||||
return !first.some(b => !second.some(a => isEqual(a, b)));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
|
||||
title: 'app_shared_connectionMenu_custom',
|
||||
isHidden: () => (
|
||||
!this.serverConfigResource.data?.supportsCustomConnections
|
||||
|| !this.projectsService.activeProject?.canCreateConnections
|
||||
|| !this.projectsService.activeProject?.canEditDataSources
|
||||
),
|
||||
onClick: () => this.openConnectionsDialog(),
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ export class SearchConnectionPluginBootstrap extends Bootstrap {
|
||||
order: 3,
|
||||
title: 'connections_connection_create_search_database',
|
||||
isHidden: () => (
|
||||
!this.projectsService.activeProject?.canCreateConnections
|
||||
!this.projectsService.activeProject?.canEditDataSources
|
||||
|| !this.permissionsService.has(EAdminPermission.admin)
|
||||
),
|
||||
onClick: () => {
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
if (state.projectId !== null && state.mode === 'create') {
|
||||
const project = this.projectsResource.get(state.projectId);
|
||||
|
||||
if (!project?.canCreateConnections) {
|
||||
if (!project?.canEditDataSources) {
|
||||
validation.error('plugin_connections_connection_form_project_invalid');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +36,12 @@ export const ProjectSelect = observer(function ProjectSelect(props: Props) {
|
||||
const value = props.value ?? projectsService.activeProject?.id;
|
||||
const projects = projectsLoader.data as ProjectInfo[];
|
||||
|
||||
const possibleOptions = projects.filter(project => project.canCreateConnections);
|
||||
const possibleOptions = projects.filter(project => project.canEditDataSources);
|
||||
|
||||
function handleProjectSelect(projectId: string) {
|
||||
const project = projectsLoader.resource.get(projectId);
|
||||
|
||||
if (project?.canCreateConnections) {
|
||||
if (project?.canEditDataSources) {
|
||||
props.onChange(projectId);
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ export const ProjectSelect = observer(function ProjectSelect(props: Props) {
|
||||
keySelector={project => project.id}
|
||||
valueSelector={project => project.name}
|
||||
titleSelector={project => project.description}
|
||||
isDisabled={project => !project.canCreateConnections}
|
||||
isDisabled={project => !project.canEditDataSources}
|
||||
readOnly={props.readOnly || possibleOptions.length <= 1}
|
||||
searchable={projects.length > 10}
|
||||
disabled={props.disabled}
|
||||
|
||||
@@ -185,7 +185,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
|
||||
}
|
||||
|
||||
if (type === ENodeMoveType.CanDrop) {
|
||||
if (targetProject?.canCreateConnections) {
|
||||
if (targetProject?.canEditDataSources) {
|
||||
move.setCanMove(true);
|
||||
}
|
||||
} else {
|
||||
@@ -337,7 +337,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
|
||||
|
||||
const project = this.projectsNavNodeService.getByNodeId(projectNode.id);
|
||||
|
||||
if (!project?.canCreateConnections) {
|
||||
if (!project?.canEditDataSources) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user