diff --git a/README.md b/README.md
index c43ad0ea7..7c1803809 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ multiple organizations. Here are some of the key features:
- Single sign-on (SSO) via [OAuth2](https://oauth.net/2/)
- No need to install or maintain local Capella clients - clients are made on
demand in an underlaying [Kubernetes](https://kubernetes.io/) cluster
-- Access to projects and models is self-managed by project leads, model owners
+- Access to projects and models is self-managed by project admins, model owners
or delegates
- Within a project a user could have read or read & write access. Read-only
users don't consume licenses in Team for Capella projects.
@@ -60,7 +60,7 @@ In addition, we have integrated commercial products:
- [pure::variants](https://www.pure-systems.com/purevariants)
- Automatic license injection
- - Access to licenses is self-managed by project leads
+ - Access to licenses is self-managed by project admins
We've prepared a small video, where we showcase the diagram cache feature and
show how you can use Capella and Jupyter in split view in the browser:
diff --git a/backend/capellacollab/projects/toolmodels/modelsources/git/gitlab/exceptions.py b/backend/capellacollab/projects/toolmodels/modelsources/git/gitlab/exceptions.py
index c50cfa818..4b20b9dfc 100644
--- a/backend/capellacollab/projects/toolmodels/modelsources/git/gitlab/exceptions.py
+++ b/backend/capellacollab/projects/toolmodels/modelsources/git/gitlab/exceptions.py
@@ -14,7 +14,7 @@ def __init__(self):
title="Insufficient Gitlab API access scope",
reason=(
"The registered token has not enough permissions to access the Gitlab API. "
- "Access scope 'read_api' is required. Please contact your project lead."
+ "Access scope 'read_api' is required. Please contact your project administrator."
),
err_code="GITLAB_ACCESS_DENIED",
)
diff --git a/backend/capellacollab/projects/toolmodels/modelsources/git/routes.py b/backend/capellacollab/projects/toolmodels/modelsources/git/routes.py
index 26ef52b8a..cb6077ab7 100644
--- a/backend/capellacollab/projects/toolmodels/modelsources/git/routes.py
+++ b/backend/capellacollab/projects/toolmodels/modelsources/git/routes.py
@@ -88,7 +88,7 @@ async def get_revisions_of_primary_git_model(
],
)
async def get_revisions_with_model_credentials(
- url: str = fastapi.Body(),
+ url: str = fastapi.Body(media_type="text/plain"),
git_model: models.DatabaseGitModel = fastapi.Depends(
injectables.get_existing_git_model
),
diff --git a/backend/capellacollab/projects/toolmodels/restrictions/routes.py b/backend/capellacollab/projects/toolmodels/restrictions/routes.py
index fee4aa8b9..402c4252a 100644
--- a/backend/capellacollab/projects/toolmodels/restrictions/routes.py
+++ b/backend/capellacollab/projects/toolmodels/restrictions/routes.py
@@ -10,15 +10,15 @@
injectables as toolmodels_injectables,
)
from capellacollab.projects.toolmodels import models as toolmodels_models
-from capellacollab.projects.users import models as projects_users_models
+from capellacollab.users import models as users_models
from . import crud, exceptions, injectables, models
router = fastapi.APIRouter(
dependencies=[
fastapi.Depends(
- auth_injectables.ProjectRoleVerification(
- required_role=projects_users_models.ProjectUserRole.ADMIN
+ auth_injectables.RoleVerification(
+ required_role=users_models.Role.ADMIN
)
)
],
diff --git a/backend/capellacollab/projects/users/exceptions.py b/backend/capellacollab/projects/users/exceptions.py
index 883771c53..7c418ded5 100644
--- a/backend/capellacollab/projects/users/exceptions.py
+++ b/backend/capellacollab/projects/users/exceptions.py
@@ -44,9 +44,9 @@ def __init__(self):
super().__init__(
status_code=status.HTTP_403_FORBIDDEN,
err_code="PERMISSION_FOR_PROJECT_LEADS_NOT_ALLOWED",
- title="Permission for project leads not allowed",
+ title="Permission for project administrator not allowed",
reason=(
- "Project leads can't be given permissions. "
+ "Project administrators can't be given permissions. "
"They already have full access to the project."
),
)
diff --git a/backend/capellacollab/projects/users/models.py b/backend/capellacollab/projects/users/models.py
index 8a76509b3..fd2ccd743 100644
--- a/backend/capellacollab/projects/users/models.py
+++ b/backend/capellacollab/projects/users/models.py
@@ -5,6 +5,7 @@
import enum
import typing as t
+import pydantic
import sqlalchemy as sa
from sqlalchemy import orm
@@ -35,7 +36,13 @@ class ProjectUser(core_pydantic.BaseModel):
class PostProjectUser(core_pydantic.BaseModel):
- role: ProjectUserRole
+ role: ProjectUserRole = pydantic.Field(
+ description=(
+ "The role of the user in the project. "
+ "Can be 'user' or 'manager'. Manager is also referred "
+ "to as project administrator in the documentation."
+ )
+ )
permission: ProjectUserPermission
username: str
reason: str
diff --git a/backend/capellacollab/projects/users/routes.py b/backend/capellacollab/projects/users/routes.py
index 80a6f2280..771c5dd30 100644
--- a/backend/capellacollab/projects/users/routes.py
+++ b/backend/capellacollab/projects/users/routes.py
@@ -225,7 +225,7 @@ def update_project_user(
],
)
def remove_user_from_project(
- reason: str = fastapi.Body(),
+ reason: str = fastapi.Body(media_type="text/plain"),
project: projects_models.DatabaseProject = fastapi.Depends(
projects_injectables.get_existing_project
),
diff --git a/backend/capellacollab/settings/modelsources/git/exceptions.py b/backend/capellacollab/settings/modelsources/git/exceptions.py
index d664cf9c9..dcf656a6a 100644
--- a/backend/capellacollab/settings/modelsources/git/exceptions.py
+++ b/backend/capellacollab/settings/modelsources/git/exceptions.py
@@ -13,7 +13,7 @@ def __init__(self):
title="Error while accessing the Git repository",
reason=(
"There was an error accessing the model. "
- "Please ask your project lead for more information. "
+ "Please ask your project administrator for more information. "
"In most cases, the credentials need to be updated."
),
err_code="GIT_REPOSITORY_ACCESS_ERROR",
diff --git a/docs/docs/development/docs.md b/docs/docs/development/docs.md
index c85cd53ac..0ee5eed23 100644
--- a/docs/docs/development/docs.md
+++ b/docs/docs/development/docs.md
@@ -101,7 +101,7 @@ subsections:
- `Project lead` |
+ `Project administrator` |
:material-check: Manage users of a project
:material-check: Manage model sources
diff --git a/docs/docs/user/sessions/troubleshooting/index.md b/docs/docs/user/sessions/troubleshooting/index.md
index 790761509..d905b2a8c 100644
--- a/docs/docs/user/sessions/troubleshooting/index.md
+++ b/docs/docs/user/sessions/troubleshooting/index.md
@@ -42,12 +42,12 @@
This happens if the loading of one of the models fails.
- Please reach out your project lead. If you are project lead, please check
+ Please reach out your project administrator. If you are project administrator, please check
the primary Git models with a matching tool version of your project.
These are used for the `read-only` session. Common mistakes are wrong
credentials, wrong entrypoints (e.g. with typos) and missing `aird`-files.
- If you have no success, please reach out your administrator. Administrators
+ If you have no success, please reach out your global administrator. They
can see the logs of read-only sessions.
diff --git a/docs/docs/user/tools/capella/troubleshooting/index.md b/docs/docs/user/tools/capella/troubleshooting/index.md
index f48e95abf..4a84c88ce 100644
--- a/docs/docs/user/tools/capella/troubleshooting/index.md
+++ b/docs/docs/user/tools/capella/troubleshooting/index.md
@@ -15,7 +15,7 @@
reported to the Eclipse Capella team directly in the
[Github repository](https://github.com/eclipse/capella/issues).
- Administrators can see the logs of all sessions to identify the issues
+ Global administrators can see the logs of all sessions to identify the issues
remotely. In addition, the session owner can also see the events in the UI.
In your session, please follow these steps:
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index c626b4ff4..cf7e91495 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -72,7 +72,7 @@ nav:
- api/swagger.md
- api/redoc.md
- api/openapi.md
- - Administrator Documentation:
+ - System Administrator Documentation:
- Introduction: admin/index.md
- Installation: admin/installation.md
- Authentication:
diff --git a/frontend/src/app/helpers/input-dialog/input-dialog.component.html b/frontend/src/app/helpers/input-dialog/input-dialog.component.html
index ac3f64313..b99b4656e 100644
--- a/frontend/src/app/helpers/input-dialog/input-dialog.component.html
+++ b/frontend/src/app/helpers/input-dialog/input-dialog.component.html
@@ -5,7 +5,7 @@
diff --git a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html
index f41ef4bcf..ea3183d4c 100644
--- a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html
+++ b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html
@@ -4,7 +4,7 @@
-->
-
+
Models
@if (projectUserService.verifyRole("manager")) {
Models
}
}
-
-
-
+
+ @if ((modelService.models$ | async) === undefined) {
+ @for (card of [0, 1, 2]; track $index) {
-
-
-
-
+ }
+ }
+ @for (model of modelService.models$ | async; track model.id) {
-
-
- {{ model.name }}
+
+
+
+ {{ model.name }}
+
+
+ {{ model.tool.name }}
+ @if (model.version) {
+ {{ model.version.name }}
+ } @else {
+ (Version not specified)
+ }
+
-
- {{ model.tool.name }}
- {{ model.version.name }}
- (Version not specified)
-
-
-
-
-
- Nature
-
- {{ model.nature.name }}
+
+
+
+ Nature
+
+ @if (model.nature) {
+ {{ model.nature.name }}
+ } @else {
+ Not specified
+ }
+
- Not specified
-
-
-
- Working mode
-
- {{ getPrimaryWorkingMode(model) }}
+
+
+ Working mode
+
+ {{ getPrimaryWorkingMode(model) }}
+
-
-
-
- {{ model.description || "This model has no description." }}
-
-
-
-
+ }
diff --git a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.ts b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.ts
index e9c79897c..c9aa24b30 100644
--- a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.ts
+++ b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.ts
@@ -2,7 +2,7 @@
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/
-import { NgIf, NgFor, AsyncPipe } from '@angular/common';
+import { AsyncPipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import {
MatAnchor,
@@ -44,8 +44,6 @@ import { ModelComplexityBadgeComponent } from './model-complexity-badge/model-co
MatTooltip,
MatIcon,
MatButton,
- NgIf,
- NgFor,
NgxSkeletonLoaderModule,
ModelComplexityBadgeComponent,
MatMiniFabAnchor,
diff --git a/frontend/src/app/projects/project-detail/model-overview/model-overview.stories.ts b/frontend/src/app/projects/project-detail/model-overview/model-overview.stories.ts
new file mode 100644
index 000000000..2305b695e
--- /dev/null
+++ b/frontend/src/app/projects/project-detail/model-overview/model-overview.stories.ts
@@ -0,0 +1,105 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
+import { ModelWrapperService } from 'src/app/projects/models/service/model.service';
+import { ProjectUserService } from 'src/app/projects/project-detail/project-users/service/project-user.service';
+import { UserWrapperService } from 'src/app/services/user/user.service';
+import { mockModel, MockModelWrapperService } from 'src/storybook/model';
+import { MockProjectUserService } from 'src/storybook/project-users';
+import { mockUser, MockUserService } from 'src/storybook/user';
+import { ModelOverviewComponent } from './model-overview.component';
+
+const meta: Meta = {
+ title: 'Model Components / Model Overview',
+ component: ModelOverviewComponent,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Loading: Story = {
+ args: {},
+};
+
+export const Overview: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: ModelWrapperService,
+ useFactory: () =>
+ new MockModelWrapperService(mockModel, [
+ { ...mockModel, name: 'mockModel1' },
+ {
+ ...mockModel,
+ name: 'mockModel2',
+ description:
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ },
+ {
+ ...mockModel,
+ name: 'ModelWithMissingInfo',
+ version: null,
+ nature: null,
+ },
+ {
+ ...mockModel,
+ name: 'Capella model',
+ tool: { ...mockModel.tool, name: 'Capella' },
+ },
+ ]),
+ },
+ ],
+ }),
+ ],
+};
+
+export const AsProjectAdmin: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: ModelWrapperService,
+ useFactory: () =>
+ new MockModelWrapperService(mockModel, [
+ { ...mockModel, name: 'mockModel1' },
+ ]),
+ },
+ {
+ provide: ProjectUserService,
+ useFactory: () => new MockProjectUserService('manager', 'write'),
+ },
+ ],
+ }),
+ ],
+};
+
+export const AsGlobalAdmin: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: ModelWrapperService,
+ useFactory: () =>
+ new MockModelWrapperService(mockModel, [
+ { ...mockModel, name: 'mockModel1' },
+ ]),
+ },
+ {
+ provide: ProjectUserService,
+ useFactory: () => new MockProjectUserService('manager', 'write'),
+ },
+ {
+ provide: UserWrapperService,
+ useFactory: () =>
+ new MockUserService({ ...mockUser, role: 'administrator' }),
+ },
+ ],
+ }),
+ ],
+};
diff --git a/frontend/src/app/projects/project-detail/project-details.component.html b/frontend/src/app/projects/project-detail/project-details.component.html
index 70fbdedbf..9ff2654a6 100644
--- a/frontend/src/app/projects/project-detail/project-details.component.html
+++ b/frontend/src/app/projects/project-detail/project-details.component.html
@@ -3,15 +3,15 @@
~ SPDX-License-Identifier: Apache-2.0
-->
-
+
-
-
+ @if (projectUserService.verifyRole("manager")) {
-
+ }
diff --git a/frontend/src/app/projects/project-detail/project-details.stories.ts b/frontend/src/app/projects/project-detail/project-details.stories.ts
new file mode 100644
index 000000000..a2b7fe528
--- /dev/null
+++ b/frontend/src/app/projects/project-detail/project-details.stories.ts
@@ -0,0 +1,37 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
+import { ProjectUserService } from 'src/app/projects/project-detail/project-users/service/project-user.service';
+import { MockProjectUserService } from 'src/storybook/project-users';
+import { ProjectDetailsComponent } from './project-details.component';
+
+const meta: Meta = {
+ title: 'Project Components / Project Details',
+ component: ProjectDetailsComponent,
+ parameters: {
+ chromatic: { viewports: [1920] },
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Loading: Story = {
+ args: {},
+};
+
+export const LoadingAsProjectLead: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: ProjectUserService,
+ useFactory: () => new MockProjectUserService('manager'),
+ },
+ ],
+ }),
+ ],
+};
diff --git a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.component.html b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.component.html
index 2afdc9eda..a05e983c8 100644
--- a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.component.html
+++ b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.component.html
@@ -4,9 +4,9 @@
-->
- Project Information
+ Project Information
@if (project !== undefined) {
diff --git a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.docs.mdx b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.docs.mdx
index b95fe4c51..30679b3a0 100644
--- a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.docs.mdx
+++ b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.docs.mdx
@@ -20,7 +20,7 @@ While loading the project, it looks the same for all users:
A "normal" project user can see the title and description:
-Project leads have the option to modify some settings:
+Project Administrators have the option to modify some settings:
This is how an archived projects looks like for normal users:
diff --git a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.stories.ts b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.stories.ts
index 23002d28f..f55b0a932 100644
--- a/frontend/src/app/projects/project-detail/project-metadata/project-metadata.stories.ts
+++ b/frontend/src/app/projects/project-detail/project-metadata/project-metadata.stories.ts
@@ -3,26 +3,11 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
-import {
- ProjectUserRole,
- ProjectUserService,
-} from 'src/app/projects/project-detail/project-users/service/project-user.service';
+import { ProjectUserService } from 'src/app/projects/project-detail/project-users/service/project-user.service';
import { mockProject } from 'src/storybook/project';
+import { MockProjectUserService } from 'src/storybook/project-users';
import { ProjectMetadataComponent } from './project-metadata.component';
-class MockProjectUserService implements Partial {
- user: ProjectUserRole;
-
- constructor(user: ProjectUserRole) {
- this.user = user;
- }
-
- verifyRole(requiredRole: ProjectUserRole): boolean {
- const roles = ['user', 'manager', 'administrator'];
- return roles.indexOf(requiredRole) <= roles.indexOf(this.user);
- }
-}
-
const meta: Meta = {
title: 'Project Components / Project Metadata',
component: ProjectMetadataComponent,
diff --git a/frontend/src/app/projects/project-detail/project-users/add-user-to-project/add-user-to-project.component.html b/frontend/src/app/projects/project-detail/project-users/add-user-to-project/add-user-to-project.component.html
index 6eab0af77..e8862821d 100644
--- a/frontend/src/app/projects/project-detail/project-users/add-user-to-project/add-user-to-project.component.html
+++ b/frontend/src/app/projects/project-detail/project-users/add-user-to-project/add-user-to-project.component.html
@@ -4,58 +4,53 @@
-->
- Add user
+ Add User to Project
|