Merge branch 'refactor/cb-2702/remove-global-project-const' into CB-2793-remove-global-project-from-te

This commit is contained in:
Aleksey Potsetsuev
2022-10-31 17:10:38 +03:00
20 changed files with 100 additions and 55 deletions
@@ -48,6 +48,9 @@ public class WebProjectInfo {
return project.getId();
}
@Property
public boolean isGlobal() { return project.getRmProject().isGlobal(); }
@Property
public boolean isShared() {
return project.getRmProject().isShared();
@@ -369,6 +369,7 @@ type NavigatorSettings {
type ProjectInfo {
id: String!
global: Boolean!
shared: Boolean!
name: String!
description: String
@@ -5,6 +5,7 @@ type RMProject {
name: String!
description: String
shared: Boolean!
global: Boolean!
createTime: DateTime!
creator: String!
@@ -235,6 +235,7 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
runInAction(() => {
if (all) {
this.data.clear();
this.resetIncludes();
}
this.set(resourceKeyList(usersList.map(user => user.userId)), usersList);
@@ -4,6 +4,7 @@ export * from './AUTH_PROVIDER_LOCAL_ID';
export * from './AuthInfoService';
export * from './AuthProviderService';
export * from './AuthProvidersResource';
export * from './AuthRolesResource';
export * from './AuthSettingsService';
export * from './DATA_CONTEXT_USER';
export * from './IAuthCredentials';
@@ -1,9 +0,0 @@
/*
* 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.
*/
export const PROJECT_GLOBAL_ID = 'g_GlobalConfiguration';
@@ -14,8 +14,6 @@ import { SharedProjectsResource } from '@cloudbeaver/core-resource-manager';
import { EPermission, SessionPermissionsResource } from '@cloudbeaver/core-root';
import { GraphQLService, ProjectInfo as SchemaProjectInfo, CachedMapResource, CachedMapAllKey, ResourceKey, ResourceKeyUtils, resourceKeyList } from '@cloudbeaver/core-sdk';
import { PROJECT_GLOBAL_ID } from './PROJECT_GLOBAL_ID';
export type ProjectInfo = SchemaProjectInfo;
@injectable()
@@ -64,12 +62,8 @@ export function projectInfoSortByName(a: ProjectInfo, b: ProjectInfo) {
return 0;
}
if (a.id === PROJECT_GLOBAL_ID) {
return -1;
}
if (b.id === PROJECT_GLOBAL_ID) {
return 1;
if (a.global !== b.global) {
return +a.global - +b.global;
}
if (a.shared !== b.shared) {
@@ -5,5 +5,4 @@ export * from './activeProjectsContext';
export * from './ProjectInfoResource';
export * from './ProjectsService';
export * from './NAV_NODE_TYPE_PROJECT';
export * from './PROJECT_GLOBAL_ID';
export { manifest as coreProjectsManifest } from './manifest';
@@ -0,0 +1,42 @@
schema:
- ../../../server/bundles/io.cloudbeaver.server/schema/schema.graphqls
- ../../../server/bundles/io.cloudbeaver.server/schema/service.core.graphqls
- ../../../server/bundles/io.cloudbeaver.server/schema/service.navigator.graphqls
- ../../../server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls
- ../../../server/bundles/io.cloudbeaver.service.metadata/schema/service.metadata.graphqls
- ../../../server/bundles/io.cloudbeaver.service.data.transfer/schema/service.data.transfer.graphqls
- ../../../server/bundles/io.cloudbeaver.service.admin/schema/service.admin.graphqls
- ../../../server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls
- ../../../server/bundles/io.cloudbeaver.service.rm/schema/service.rm.graphqls
documents:
- ./src/**/*.gql
generates:
src/sdk.ts:
plugins:
- add:
content: '/* eslint-disable */'
- typescript
- typescript-operations
- typescript-graphql-request
config:
skipTypename: true
documentMode : 'string'
useTypeImports: true
avoidOptionals:
field: false
inputValue: false
object: false
maybeValue: T # T | null
declarationKind:
union: type
type: interface
input: interface
scalar: interface
arguments: interface
scalars:
Object: any
JSON: "{ [key: string]: any }"
DateTime: any
hooks:
afterAllFileWrite:
- eslint --fix
@@ -2,6 +2,7 @@ fragment SharedProject on RMProject {
id
name
shared
global
description
projectPermissions
}
@@ -2,6 +2,7 @@ query getProjectList {
projects: listProjects {
id
shared
global
name
description
canEditDataSources
@@ -3,6 +3,7 @@ query getResourceProjectList {
id
name
shared
global
description
projectPermissions
}
+11 -6
View File
@@ -877,6 +877,7 @@ export interface ProjectInfo {
canViewDataSources: Scalars['Boolean'];
canViewResources: Scalars['Boolean'];
description?: Maybe<Scalars['String']>;
global: Scalars['Boolean'];
id: Scalars['String'];
name: Scalars['String'];
shared: Scalars['Boolean'];
@@ -1383,6 +1384,7 @@ export interface RmProject {
createTime: Scalars['DateTime'];
creator: Scalars['String'];
description?: Maybe<Scalars['String']>;
global: Scalars['Boolean'];
id: Scalars['ID'];
name: Scalars['String'];
projectPermissions: Array<Scalars['String']>;
@@ -2333,7 +2335,7 @@ export type SqlScriptInfoFragment = { queries: Array<{ start: number, end: numbe
export type SessionStateFragment = { createTime: string, lastAccessTime: string, cacheExpired: boolean, locale: string, actionParameters?: any, valid: boolean, remainingTime: number };
export type SharedProjectFragment = { id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> };
export type SharedProjectFragment = { id: string, name: string, shared: boolean, global: boolean, description?: string, projectPermissions: Array<string> };
export type UserConnectionAuthPropertiesFragment = { id?: string, displayName?: string, description?: string, category?: string, dataType?: string, value?: any, validValues?: Array<any>, defaultValue?: any, length: ObjectPropertyLength, features: Array<string>, order: number };
@@ -2537,7 +2539,7 @@ export type NavRenameNodeMutation = { navRenameNode?: string };
export type GetProjectListQueryVariables = Exact<{ [key: string]: never; }>;
export type GetProjectListQuery = { projects: Array<{ id: string, shared: boolean, name: string, description?: string, canEditDataSources: boolean, canViewDataSources: boolean, canEditResources: boolean, canViewResources: boolean }> };
export type GetProjectListQuery = { projects: Array<{ id: string, shared: boolean, global: boolean, name: string, description?: string, canEditDataSources: boolean, canViewDataSources: boolean, canEditResources: boolean, canViewResources: boolean }> };
export type CreateProjectMutationVariables = Exact<{
projectId?: InputMaybe<Scalars['ID']>;
@@ -2546,7 +2548,7 @@ export type CreateProjectMutationVariables = Exact<{
}>;
export type CreateProjectMutation = { project: { id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> } };
export type CreateProjectMutation = { project: { id: string, name: string, shared: boolean, global: boolean, description?: string, projectPermissions: Array<string> } };
export type CreateResourceMutationVariables = Exact<{
projectId: Scalars['String'];
@@ -2578,7 +2580,7 @@ export type GetProjectQueryVariables = Exact<{
}>;
export type GetProjectQuery = { project: { id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> } };
export type GetProjectQuery = { project: { id: string, name: string, shared: boolean, global: boolean, description?: string, projectPermissions: Array<string> } };
export type GetProjectGrantedPermissionsQueryVariables = Exact<{
projectId: Scalars['String'];
@@ -2606,12 +2608,12 @@ export type GetResourceListQuery = { resources: Array<{ name: string, folder: bo
export type GetResourceProjectListQueryVariables = Exact<{ [key: string]: never; }>;
export type GetResourceProjectListQuery = { projects: Array<{ id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> }> };
export type GetResourceProjectListQuery = { projects: Array<{ id: string, name: string, shared: boolean, global: boolean, description?: string, projectPermissions: Array<string> }> };
export type GetSharedProjectsQueryVariables = Exact<{ [key: string]: never; }>;
export type GetSharedProjectsQuery = { projects: Array<{ id: string, name: string, shared: boolean, description?: string, projectPermissions: Array<string> }> };
export type GetSharedProjectsQuery = { projects: Array<{ id: string, name: string, shared: boolean, global: boolean, description?: string, projectPermissions: Array<string> }> };
export type GetSubjectProjectsPermissionsQueryVariables = Exact<{
subjectId: Scalars['String'];
@@ -3153,6 +3155,7 @@ export const SharedProjectFragmentDoc = `
id
name
shared
global
description
projectPermissions
}
@@ -4127,6 +4130,7 @@ export const GetProjectListDocument = `
projects: listProjects {
id
shared
global
name
description
canEditDataSources
@@ -4213,6 +4217,7 @@ export const GetResourceProjectListDocument = `
id
name
shared
global
description
projectPermissions
}
@@ -6,18 +6,17 @@
* you may not use this file except in compliance with the License.
*/
import { computed } from 'mobx';
import { observer } from 'mobx-react-lite';
import { useEffect, useMemo } from 'react';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES, ColoredContainer, Container, Group,
BASE_CONTAINERS_STYLES, ColoredContainer, Container, getComputed, Group,
InfoItem, Loader, TextPlaceholder, useMapResource, useStyles, useTranslate
} from '@cloudbeaver/core-blocks';
import { ConnectionInfoProjectKey, ConnectionInfoResource, DBDriverResource, isCloudConnection } from '@cloudbeaver/core-connections';
import { ConnectionInfoResource, DBDriverResource, isCloudConnection } from '@cloudbeaver/core-connections';
import type { TLocalizationToken } from '@cloudbeaver/core-localization';
import { PROJECT_GLOBAL_ID } from '@cloudbeaver/core-projects';
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
import { TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
@@ -53,22 +52,28 @@ export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = ob
const { selected } = useTab(tabId);
const loaded = state.state.loaded;
const projects = useMapResource(GrantedConnections, ProjectInfoResource, CachedMapAllKey);
const dbDriverResource = useMapResource(
GrantedConnections,
DBDriverResource,
CachedMapAllKey,
{ active: selected }
);
const connections = useMapResource(
GrantedConnections,
ConnectionInfoResource,
ConnectionInfoProjectKey(PROJECT_GLOBAL_ID),
CachedMapAllKey,
{ active: selected }
);
const grantedConnections = useMemo(() => computed(() => connections.resource.values
const globalConnections = connections.resource.values
.filter(({ projectId }) => projects.resource.get(projectId)?.global);
const grantedConnections = getComputed(() => globalConnections
.filter(connection => state.state.grantedSubjects.includes(connection.id))
), [state.state.grantedSubjects, connections.resource]);
);
useEffect(() => {
if (selected && !loaded) {
@@ -82,7 +87,7 @@ export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = ob
let info: TLocalizationToken | null = null;
const cloudExists = connections.resource.values.some(isCloudConnection);
const cloudExists = globalConnections.some(isCloudConnection);
if (cloudExists) {
info = 'cloud_connections_access_placeholder';
@@ -93,10 +98,10 @@ export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = ob
}
return styled(style)(
<Loader state={[connections, dbDriverResource, state.state]}>
<Loader state={[connections, dbDriverResource, projects, state.state]}>
{() => styled(style)(
<ColoredContainer parent gap vertical>
{!connections.resource.values.length ? (
{!globalConnections.length ? (
<Group large>
<TextPlaceholder>{translate('administration_teams_team_granted_connections_empty')}</TextPlaceholder>
</Group>
@@ -105,14 +110,14 @@ export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = ob
{info && <InfoItem info={info} />}
<Container gap overflow>
<GrantedConnectionList
grantedConnections={grantedConnections.get()}
grantedConnections={grantedConnections}
disabled={formState.disabled}
onEdit={state.edit}
onRevoke={state.revoke}
/>
{state.state.editing && (
<ConnectionList
connectionList={connections.resource.values}
connectionList={globalConnections}
grantedSubjects={state.state.grantedSubjects}
disabled={formState.disabled}
onGrant={state.grant}
@@ -8,17 +8,16 @@
import { observable, computed, makeObservable } from 'mobx';
import { AdminUser, compareTeams, isLocalUser, TeamInfo, TeamsResource, UsersResource } from '@cloudbeaver/core-authentication';
import { AuthRolesResource } from '@cloudbeaver/core-authentication/src/AuthRolesResource';
import { ConnectionInfoProjectKey, ConnectionInfoResource, DatabaseConnection, DBDriverResource } from '@cloudbeaver/core-connections';
import { AdminUser, AuthRolesResource, compareTeams, isLocalUser, TeamInfo, TeamsResource, UsersResource } from '@cloudbeaver/core-authentication';
import { ConnectionInfoResource, DatabaseConnection, DBDriverResource } from '@cloudbeaver/core-connections';
import { injectable, IInitializableController, IDestructibleController } from '@cloudbeaver/core-di';
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
import { ENotificationType, NotificationService } from '@cloudbeaver/core-events';
import { Executor, ExecutorInterrupter } from '@cloudbeaver/core-executor';
import type { TLocalizationToken } from '@cloudbeaver/core-localization';
import { ErrorDetailsDialog } from '@cloudbeaver/core-notifications';
import { PROJECT_GLOBAL_ID } from '@cloudbeaver/core-projects';
import { GQLErrorCatcher, AdminConnectionGrantInfo, AdminSubjectType, AdminUserInfo } from '@cloudbeaver/core-sdk';
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
import { GQLErrorCatcher, AdminConnectionGrantInfo, AdminSubjectType, AdminUserInfo, CachedMapAllKey } from '@cloudbeaver/core-sdk';
import { MetadataMap } from '@cloudbeaver/core-utils';
import type { IUserFormState } from './UserFormService';
@@ -50,7 +49,8 @@ export class UserFormController implements IInitializableController, IDestructib
partsState: MetadataMap<string, any>;
get connections(): DatabaseConnection[] {
return this.connectionInfoResource.get(ConnectionInfoProjectKey(PROJECT_GLOBAL_ID)) as DatabaseConnection[];
return this.connectionInfoResource.values
.filter(({ projectId }) => this.projectInfoResource.get(projectId)?.global) as DatabaseConnection[];
}
get teams(): TeamInfo[] {
@@ -73,6 +73,7 @@ export class UserFormController implements IInitializableController, IDestructib
private editing!: boolean;
constructor(
private readonly projectInfoResource: ProjectInfoResource,
private readonly notificationService: NotificationService,
private readonly commonDialogService: CommonDialogService,
private readonly teamsResource: TeamsResource,
@@ -172,7 +173,7 @@ export class UserFormController implements IInitializableController, IDestructib
await this.saveUserStatus();
await this.saveConnectionPermissions();
await this.saveMetaParameters();
user = await this.usersResource.refresh(this.user.userId);
user = await this.usersResource.refresh(this.user.userId, ['includeMetaParameters']);
this.notificationService.logSuccess({ title: 'authentication_administration_user_updated' });
}
@@ -363,7 +364,8 @@ export class UserFormController implements IInitializableController, IDestructib
private async loadConnections() {
try {
await this.dbDriverResource.loadAll();
await this.connectionInfoResource.load(ConnectionInfoProjectKey(PROJECT_GLOBAL_ID));
await this.projectInfoResource.load(CachedMapAllKey);
await this.connectionInfoResource.load(CachedMapAllKey);
} catch (exception: any) {
this.setStatusMessage('authentication_administration_user_connections_access_connections_load_fail', ENotificationType.Error);
}
@@ -10,8 +10,7 @@ import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import styled, { css } from 'reshadow';
import { UserMetaParametersResource } from '@cloudbeaver/core-authentication';
import { AuthRolesResource } from '@cloudbeaver/core-authentication/src/AuthRolesResource';
import { AuthRolesResource, UserMetaParametersResource } from '@cloudbeaver/core-authentication';
import { BASE_CONTAINERS_STYLES, ColoredContainer, Container, FieldCheckbox, Group, GroupTitle, InputField, Loader, ObjectPropertyInfoForm, useDataResource, useTranslate, useStyles, Combobox } from '@cloudbeaver/core-blocks';
import type { TabContainerPanelComponent } from '@cloudbeaver/core-ui';
@@ -16,8 +16,6 @@ import {
import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { UsersAdministrationService } from '../UsersAdministrationService';
import { UserEdit } from './UserEdit';
@@ -10,8 +10,7 @@ import { observer } from 'mobx-react-lite';
import styled, { css, use } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, IAdministrationItemSubItem } from '@cloudbeaver/core-administration';
import { AdminUser, UsersResource } from '@cloudbeaver/core-authentication';
import { AuthRolesResource } from '@cloudbeaver/core-authentication/src/AuthRolesResource';
import { AdminUser, AuthRolesResource, UsersResource } from '@cloudbeaver/core-authentication';
import { Table, TableHeader, TableColumnHeader, TableBody, TableSelect, useMapResource, ToolsAction, ToolsPanel, Loader, BASE_LAYOUT_GRID_STYLES, useTranslate, useStyles, useDataResource } from '@cloudbeaver/core-blocks';
import { useController, useService } from '@cloudbeaver/core-di';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
@@ -10,7 +10,7 @@ import { AdministrationScreenService, EAdminPermission } from '@cloudbeaver/core
import { ConnectionInfoResource, createConnectionParam, IConnectionInfoParams } from '@cloudbeaver/core-connections';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { executorHandlerFilter, IExecutionContextProvider } from '@cloudbeaver/core-executor';
import { PROJECT_GLOBAL_ID } from '@cloudbeaver/core-projects';
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
import { PermissionsService } from '@cloudbeaver/core-root';
import type { MetadataValueGetter } from '@cloudbeaver/core-utils';
import { connectionConfigContext, ConnectionFormService, connectionFormStateContext, IConnectionFormProps, IConnectionFormState, IConnectionFormSubmitData } from '@cloudbeaver/plugin-connections';
@@ -27,6 +27,7 @@ export class ConnectionAccessTabService extends Bootstrap {
private readonly administrationScreenService: AdministrationScreenService,
private readonly connectionInfoResource: ConnectionInfoResource,
private readonly permissionsResource: PermissionsService,
private readonly projectInfoResource: ProjectInfoResource,
) {
super();
this.key = 'access';
@@ -65,7 +66,8 @@ export class ConnectionAccessTabService extends Bootstrap {
private isAccessTabActive(state: IConnectionFormState): boolean {
return (
state.projectId === PROJECT_GLOBAL_ID
state.projectId !== null
&& this.projectInfoResource.get(state.projectId)?.global === true
&& this.permissionsResource.has(EAdminPermission.admin)
);
}
@@ -35,7 +35,6 @@ import {
} from '@cloudbeaver/core-blocks';
import { DatabaseAuthModelsResource, DBDriverResource, isLocalConnection } from '@cloudbeaver/core-connections';
import { useService } from '@cloudbeaver/core-di';
import { PROJECT_GLOBAL_ID } from '@cloudbeaver/core-projects';
import { CachedMapEmptyKey, DriverConfigurationType, resourceKeyList } from '@cloudbeaver/core-sdk';
import type { TabContainerPanelComponent } from '@cloudbeaver/core-ui';
import { useAuthenticationAction } from '@cloudbeaver/core-ui';
@@ -298,7 +297,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
{translate('connections_connection_name')}
</InputField>
<ProjectSelect
value={state.projectId ?? PROJECT_GLOBAL_ID}
value={state.projectId}
readOnly={readonly || edit}
disabled={disabled}
autoHide