From 5f55dbdde1f80b56cd9b81e9cd074bc59354c411 Mon Sep 17 00:00:00 2001 From: Lucas Fernandez Date: Fri, 8 Nov 2024 20:43:14 +0100 Subject: [PATCH 01/16] Revamp docs & codebase (#542) * Revamp docs Signed-off-by: lucferbux * Refactor codebase to improve code handling Signed-off-by: lucferbux * Fix patternfly 6 isue Signed-off-by: lucferbux * Enhance TODOs Signed-off-by: lucferbux * Update clients/ui/scripts/deploy_kind_cluster.sh Co-authored-by: Alex Creasy Signed-off-by: Lucas Fernandez * Add user token in kind Signed-off-by: lucferbux --------- Signed-off-by: lucferbux Signed-off-by: Lucas Fernandez Co-authored-by: Alex Creasy --- README.md | 1 + clients/ui/Makefile | 32 ++++ clients/ui/README.md | 48 +++++ clients/ui/api/openapi/mod-arch.yaml | 172 +++++++++++++++--- clients/ui/docker-compose.yaml | 3 +- clients/ui/frontend/Dockerfile | 2 +- clients/ui/frontend/README.md | 2 +- clients/ui/frontend/docs/dev-setup.md | 4 - .../cypress/cypress/pages/appChrome.ts | 2 +- .../cypress/support/commands/application.ts | 4 +- .../mocked/modelRegistry/modelRegistry.cy.ts | 51 ++---- .../cypress/tests/mocked/modelVersions.cy.ts | 2 +- clients/ui/frontend/src/app/App.tsx | 10 +- clients/ui/frontend/src/app/AppContext.ts | 2 +- clients/ui/frontend/src/app/AppRoutes.tsx | 4 +- .../app/context/useModelRegistryAPIState.tsx | 6 +- .../app/hooks/useModelArtifactsByVersionId.ts | 5 +- .../src/app/hooks/useModelRegistries.ts | 7 +- .../src/app/hooks/useModelVersionById.ts | 5 +- .../useModelVersionsByRegisteredModel.ts | 5 +- .../src/app/hooks/useRegisteredModelById.ts | 5 +- .../src/app/hooks/useRegisteredModels.ts | 5 +- .../modelRegistry/ModelRegistryCoreLoader.tsx | 6 +- .../modelRegistry/ModelRegistryRoutes.tsx | 2 +- .../screens/InvalidModelRegistry.tsx | 2 +- .../ModelPropertiesDescriptionListGroup.tsx | 2 +- .../screens/ModelPropertiesTableRow.tsx | 4 +- .../modelRegistry/screens/ModelRegistry.tsx | 6 +- .../screens/ModelRegistrySelector.tsx | 2 +- .../ModelVersionDetails.tsx | 2 +- .../ModelVersionDetailsView.tsx | 10 +- .../ModelVersions/ModelDetailsView.tsx | 6 +- .../ModelVersions/ModelVersionListView.tsx | 6 +- .../screens/ModelVersions/ModelVersions.tsx | 2 +- .../ModelVersions/ModelVersionsTable.tsx | 4 +- .../ModelVersionsTableColumns.ts | 2 +- .../ArchiveModelVersionDetails.tsx | 2 +- .../ModelVersionArchiveDetails.tsx | 2 +- .../ModelVersionsArchive.tsx | 2 +- .../ModelVersionsArchiveListView.tsx | 4 +- .../ModelVersionsArchiveTable.tsx | 4 +- .../screens/RegisterModel/RegisterModel.tsx | 6 +- .../screens/RegisterModel/RegisterVersion.tsx | 4 +- .../RegistrationCommonFormSections.tsx | 7 +- .../usePrefillRegisterVersionFields.ts | 2 +- .../RegisterModel/useRegisterModelData.ts | 4 +- .../useRegistrationCommonState.ts | 2 +- .../RegisteredModelListView.tsx | 6 +- .../RegisteredModels/RegisteredModelTable.tsx | 4 +- .../RegisteredModelsTableColumns.ts | 2 +- .../RegisteredModelsTableToolbar.tsx | 25 ++- .../RegisteredModelArchiveDetails.tsx | 2 +- .../RegisteredModelsArchive.tsx | 2 +- .../RegisteredModelsArchiveListView.tsx | 4 +- .../RegisteredModelsArchiveTable.tsx | 4 +- .../screens/__tests__/utils.spec.ts | 2 +- .../components/ArchiveModelVersionModal.tsx | 2 +- .../ArchiveRegisteredModelModal.tsx | 2 +- .../screens/components/ModelLabels.tsx | 2 +- .../screens/components/ModelTimestamp.tsx | 2 +- .../components/RestoreModelVersionModal.tsx | 2 +- .../components/RestoreRegisteredModel.tsx | 2 +- .../app/pages/modelRegistry/screens/utils.ts | 4 +- .../pages/settings/ModelRegistriesTable.tsx | 4 +- .../settings/ModelRegistriesTableRow.tsx | 2 +- .../pages/settings/ModelRegistrySettings.tsx | 6 +- .../src/app/pages/settings/columns.ts | 4 +- clients/ui/frontend/src/app/types.ts | 2 +- clients/ui/frontend/src/app/useUser.tsx | 0 clients/ui/frontend/src/app/utils.ts | 2 +- clients/ui/frontend/src/index.tsx | 2 +- .../api/__tests__/errorUtils.spec.ts | 6 +- .../api/__tests__/service.spec.ts | 10 +- .../src/{app => shared}/api/apiUtils.ts | 19 +- .../src/{app => shared}/api/errorUtils.ts | 5 +- .../frontend/src/{app => shared}/api/k8s.ts | 6 +- .../src/{app => shared}/api/service.ts | 6 +- .../frontend/src/{app => shared}/api/types.ts | 0 .../src/{app => shared}/api/useAPIState.ts | 2 +- .../components/ApplicationsPage.tsx | 0 .../DashboardDescriptionListGroup.scss | 0 .../DashboardDescriptionListGroup.tsx | 2 +- .../components/DashboardEmptyTableView.tsx | 0 .../components/DashboardHelpTooltip.tsx | 0 .../components/DashboardModalFooter.tsx | 0 .../components/DashboardSearchField.tsx | 2 +- .../EditableLabelsDescriptionListGroup.tsx | 2 +- .../EditableTextDescriptionListGroup.tsx | 2 +- .../components/EmptyStateErrorMessage.tsx | 0 .../InlineTruncatedClipboardCopy.scss | 0 .../InlineTruncatedClipboardCopy.tsx | 0 .../components/MarkdownView.scss | 0 .../components/MarkdownView.tsx | 2 +- .../components/SimpleSelect.scss | 0 .../components/SimpleSelect.tsx | 0 .../components/ToastNotification.tsx | 0 .../components/ToastNotifications.tsx | 0 .../browserStorage/BrowserStorageContext.tsx | 4 +- .../components/browserStorage/index.ts | 0 .../components/design/CollapsibleSection.tsx | 0 .../components/design/DividedGallery.scss | 0 .../components/design/DividedGallery.tsx | 0 .../components/design/DividedGalleryItem.tsx | 0 .../components/design/HeaderIcon.tsx | 2 +- .../components/design/InfoGalleryItem.tsx | 4 +- .../components/design/ScrolledGallery.tsx | 0 .../components/design/TitleWithIcon.tsx | 2 +- .../components/design/TypeBorderCard.scss | 0 .../components/design/TypeBorderedCard.tsx | 2 +- .../components/design/utils.ts | 0 .../components/design/vars.scss | 0 .../components/pf-overrides/FormSection.scss | 0 .../components/pf-overrides/FormSection.tsx | 0 .../components/table/CheckboxTd.tsx | 0 .../components/table/Table.tsx | 2 +- .../components/table/TableBase.tsx | 2 +- .../table/TableRowTitleDescription.tsx | 2 +- .../table/__tests__/useCheckboxTable.spec.ts | 2 +- .../{app => shared}/components/table/const.ts | 0 .../{app => shared}/components/table/index.ts | 0 .../{app => shared}/components/table/types.ts | 0 .../components/table/useCheckboxTable.ts | 2 +- .../components/table/useCheckboxTableBase.ts | 0 .../components/table/useTableColumnSort.ts | 0 .../src/{app => shared/hooks}/useSettings.tsx | 12 +- .../hooks}/useTimeBasedRefresh.ts | 4 +- .../src/{ => shared}/style/MUI-theme.scss | 0 .../frontend/src/{ => shared}/typeHelpers.ts | 0 clients/ui/frontend/src/{ => shared}/types.ts | 10 +- .../ui/frontend/src/shared/utilities/const.ts | 6 + .../src/{ => shared}/utilities/markdown.ts | 0 .../src/{ => shared}/utilities/time.ts | 2 +- .../utilities/useDebounceCallback.ts | 0 .../utilities/useDeepCompareMemoize.ts | 0 .../utilities/useEventListener.ts | 0 .../{ => shared}/utilities/useFetchState.ts | 2 +- .../utilities/useGenericObjectState.ts | 2 +- clients/ui/frontend/src/utilities/const.ts | 4 - clients/ui/manifests/base/kustomization.yaml | 1 + .../base/model-registry-bff-deployment.yaml | 1 + .../base/model-registry-bff-role.yaml | 2 +- .../base/model-registry-service-account.yaml | 4 + .../base/model-registry-ui-deployment.yaml | 3 + .../ui/manifests/user-rbac/admin-rbac.yaml | 18 ++ .../ui/manifests/user-rbac/kustomization.yaml | 5 + clients/ui/scripts/deploy_kind_cluster.sh | 55 ++++++ 146 files changed, 546 insertions(+), 234 deletions(-) create mode 100644 clients/ui/Makefile create mode 100644 clients/ui/README.md delete mode 100644 clients/ui/frontend/src/app/useUser.tsx rename clients/ui/frontend/src/{app => shared}/api/__tests__/errorUtils.spec.ts (86%) rename clients/ui/frontend/src/{app => shared}/api/__tests__/service.spec.ts (98%) rename clients/ui/frontend/src/{app => shared}/api/apiUtils.ts (87%) rename clients/ui/frontend/src/{app => shared}/api/errorUtils.ts (81%) rename clients/ui/frontend/src/{app => shared}/api/k8s.ts (73%) rename clients/ui/frontend/src/{app => shared}/api/service.ts (98%) rename clients/ui/frontend/src/{app => shared}/api/types.ts (100%) rename clients/ui/frontend/src/{app => shared}/api/useAPIState.ts (94%) rename clients/ui/frontend/src/{app => shared}/components/ApplicationsPage.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/DashboardDescriptionListGroup.scss (100%) rename clients/ui/frontend/src/{ => shared}/components/DashboardDescriptionListGroup.tsx (98%) rename clients/ui/frontend/src/{app => shared}/components/DashboardEmptyTableView.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/DashboardHelpTooltip.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/DashboardModalFooter.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/DashboardSearchField.tsx (97%) rename clients/ui/frontend/src/{ => shared}/components/EditableLabelsDescriptionListGroup.tsx (99%) rename clients/ui/frontend/src/{ => shared}/components/EditableTextDescriptionListGroup.tsx (97%) rename clients/ui/frontend/src/{app => shared}/components/EmptyStateErrorMessage.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/InlineTruncatedClipboardCopy.scss (100%) rename clients/ui/frontend/src/{ => shared}/components/InlineTruncatedClipboardCopy.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/MarkdownView.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/MarkdownView.tsx (92%) rename clients/ui/frontend/src/{app => shared}/components/SimpleSelect.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/SimpleSelect.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/ToastNotification.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/ToastNotifications.tsx (100%) rename clients/ui/frontend/src/{ => shared}/components/browserStorage/BrowserStorageContext.tsx (96%) rename clients/ui/frontend/src/{ => shared}/components/browserStorage/index.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/design/CollapsibleSection.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/design/DividedGallery.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/design/DividedGallery.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/design/DividedGalleryItem.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/design/HeaderIcon.tsx (95%) rename clients/ui/frontend/src/{app => shared}/components/design/InfoGalleryItem.tsx (92%) rename clients/ui/frontend/src/{app => shared}/components/design/ScrolledGallery.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/design/TitleWithIcon.tsx (95%) rename clients/ui/frontend/src/{app => shared}/components/design/TypeBorderCard.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/design/TypeBorderedCard.tsx (90%) rename clients/ui/frontend/src/{app => shared}/components/design/utils.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/design/vars.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/pf-overrides/FormSection.scss (100%) rename clients/ui/frontend/src/{app => shared}/components/pf-overrides/FormSection.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/table/CheckboxTd.tsx (100%) rename clients/ui/frontend/src/{app => shared}/components/table/Table.tsx (97%) rename clients/ui/frontend/src/{app => shared}/components/table/TableBase.tsx (99%) rename clients/ui/frontend/src/{app => shared}/components/table/TableRowTitleDescription.tsx (95%) rename clients/ui/frontend/src/{app => shared}/components/table/__tests__/useCheckboxTable.spec.ts (97%) rename clients/ui/frontend/src/{app => shared}/components/table/const.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/table/index.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/table/types.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/table/useCheckboxTable.ts (91%) rename clients/ui/frontend/src/{app => shared}/components/table/useCheckboxTableBase.ts (100%) rename clients/ui/frontend/src/{app => shared}/components/table/useTableColumnSort.ts (100%) rename clients/ui/frontend/src/{app => shared/hooks}/useSettings.tsx (84%) rename clients/ui/frontend/src/{app => shared/hooks}/useTimeBasedRefresh.ts (92%) rename clients/ui/frontend/src/{ => shared}/style/MUI-theme.scss (100%) rename clients/ui/frontend/src/{ => shared}/typeHelpers.ts (100%) rename clients/ui/frontend/src/{ => shared}/types.ts (64%) create mode 100644 clients/ui/frontend/src/shared/utilities/const.ts rename clients/ui/frontend/src/{ => shared}/utilities/markdown.ts (100%) rename clients/ui/frontend/src/{ => shared}/utilities/time.ts (94%) rename clients/ui/frontend/src/{ => shared}/utilities/useDebounceCallback.ts (100%) rename clients/ui/frontend/src/{ => shared}/utilities/useDeepCompareMemoize.ts (100%) rename clients/ui/frontend/src/{ => shared}/utilities/useEventListener.ts (100%) rename clients/ui/frontend/src/{ => shared}/utilities/useFetchState.ts (99%) rename clients/ui/frontend/src/{ => shared}/utilities/useGenericObjectState.ts (92%) delete mode 100644 clients/ui/frontend/src/utilities/const.ts create mode 100644 clients/ui/manifests/base/model-registry-service-account.yaml create mode 100644 clients/ui/manifests/user-rbac/admin-rbac.yaml create mode 100644 clients/ui/manifests/user-rbac/kustomization.yaml create mode 100755 clients/ui/scripts/deploy_kind_cluster.sh diff --git a/README.md b/README.md index ef8f66a11..37ae95883 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Model registry provides a central repository for model developers to store and m - [playground](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/kubeflow/model-registry/main/api/openapi/model-registry.yaml) - [license scanning](https://github.com/kubeflow/model-registry/issues/323) - [monitoring image quality](https://github.com/kubeflow/model-registry/issues/327) +8. [UI](.clients/ui/README.md) ## Pre-requisites: - go >= 1.21 diff --git a/clients/ui/Makefile b/clients/ui/Makefile new file mode 100644 index 000000000..addcf8986 --- /dev/null +++ b/clients/ui/Makefile @@ -0,0 +1,32 @@ +CONTAINER_TOOL ?= docker + +.PHONY: all +all: build + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +.PHONY: dev-install-dependencies +dev-install-dependencies: + cd frontend && npm install + +.PHONY: dev-bff +dev-bff: + cd bff && make run PORT=4000 MOCK_K8S_CLIENT=true MOCK_MR_CLIENT=true + +.PHONY: dev-frontend +dev-frontend: + cd frontend && npm run start:dev + +.PHONY: dev-start +dev-start: + make -j 2 dev-bff dev-frontend + +.PHONY: docker-compose +docker-compose: + $(CONTAINER_TOOL) compose -f docker-compose.yaml up + +.PHONY: kind-deployment +kind-deployment: + ./scripts/deploy_kind_cluster.sh diff --git a/clients/ui/README.md b/clients/ui/README.md new file mode 100644 index 000000000..fe7b80a69 --- /dev/null +++ b/clients/ui/README.md @@ -0,0 +1,48 @@ +[frontend requirements]: ./frontend/docs/dev-setup.md#requirements +[BFF requirements]: ./bff/README.md#pre-requisites +[frontend dev setup]: ./frontend/docs/dev-setup.md#development +[BFF dev setup]: ./bff/README.md#development + +# Model Registry UI + +## Overview + +The Model Registry UI is a standalone web app for Kubeflow Model Registry. In this repository, you will find the frontend and backend for the Model Registry UI. + +## Prerequisites + +* [Frontend requirements] +* [BFF requirements] + +## Set Up + +### Development + +To run the a mocked dev environment you can either: + +* Use the makefile command to install dependencies `make dev-install-dependencies` and then start the dev environment `make dev-start`. + +* Or follow the [frontend dev setup] and [BFF dev setup]. + +### Docker deployment + +To build the Model Registry UI container, run the following command: + +```shell +make docker-compose +``` + +### Kubernetes Deployment + +For a in-depth guide on how to deploy the Model Registry UI, please refer to the [local kubernetes deployment](./bff/docs/dev-guide.md) documentation. + +To quickly enable the Model Registry UI in your Kind cluster, you can use the following command: + +```shell +make kind-deployment +``` + +## OpenAPI Specification + +You can find the OpenAPI specification for the Model Registry UI in the [openapi](./api/openapi) directory. +A live version of the OpenAPI specification can be found [here](https://editor.swagger.io/?url=https://raw.githubusercontent.com/kubeflow/model-registry/main/clients/ui/api/openapi/mod-arch.yaml). diff --git a/clients/ui/api/openapi/mod-arch.yaml b/clients/ui/api/openapi/mod-arch.yaml index 3479de762..d17494682 100644 --- a/clients/ui/api/openapi/mod-arch.yaml +++ b/clients/ui/api/openapi/mod-arch.yaml @@ -86,7 +86,13 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/ModelVersionUpdate" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelVersionUpdate" required: true tags: - ModelRegistryService @@ -141,7 +147,13 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/RegisteredModelCreate" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/RegisteredModelCreate" required: true tags: - ModelRegistryService @@ -186,7 +198,13 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/RegisteredModelUpdate" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/RegisteredModelUpdate" required: true tags: - ModelRegistryService @@ -244,7 +262,13 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/Artifact" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/Artifact" required: true tags: - ModelRegistryService @@ -305,7 +329,13 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/ModelVersion" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelVersion" required: true tags: - ModelRegistryService @@ -972,99 +1002,195 @@ components: content: application/json: schema: - $ref: "#/components/schemas/Config" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/Config" description: A response containing a list of ModelArtifact entities. ModelRegistryRespone: content: application/json: schema: - type: array - items: - $ref: "#/components/schemas/ModelRegistry" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + type: array + items: + $ref: "#/components/schemas/ModelRegistry" description: A response containing a list of ModelArtifact entities. ModelArtifactListResponse: content: application/json: schema: - $ref: "#/components/schemas/ModelArtifactList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelArtifactList" description: A response containing a list of ModelArtifact entities. ModelArtifactResponse: content: application/json: schema: - $ref: "#/components/schemas/ModelArtifact" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelArtifact" description: A response containing a `ModelArtifact` entity. ModelVersionListResponse: content: application/json: schema: - $ref: "#/components/schemas/ModelVersionList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelVersionList" description: A response containing a list of `ModelVersion` entities. ModelVersionResponse: content: application/json: schema: - $ref: "#/components/schemas/ModelVersion" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ModelVersion" description: A response containing a `ModelVersion` entity. RegisteredModelListResponse: content: application/json: schema: - $ref: "#/components/schemas/RegisteredModelList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/RegisteredModelList" description: A response containing a list of `RegisteredModel` entities. RegisteredModelResponse: content: application/json: schema: - $ref: "#/components/schemas/RegisteredModel" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/RegisteredModel" description: A response containing a `RegisteredModel` entity. ArtifactResponse: content: application/json: schema: - $ref: "#/components/schemas/Artifact" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/Artifact" description: A response containing an `Artifact` entity. ArtifactListResponse: content: application/json: schema: - $ref: "#/components/schemas/ArtifactList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ArtifactList" description: A response containing a list of `Artifact` entities. ServingEnvironmentListResponse: content: application/json: schema: - $ref: "#/components/schemas/ServingEnvironmentList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ServingEnvironmentList" description: A response containing a list of `ServingEnvironment` entities. ServingEnvironmentResponse: content: application/json: schema: - $ref: "#/components/schemas/ServingEnvironment" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ServingEnvironment" description: A response containing a `ServingEnvironment` entity. InferenceServiceListResponse: content: application/json: schema: - $ref: "#/components/schemas/InferenceServiceList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/InferenceServiceList" description: A response containing a list of `InferenceService` entities. InferenceServiceResponse: content: application/json: schema: - $ref: "#/components/schemas/InferenceService" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/InferenceService" description: A response containing a `InferenceService` entity. ServeModelListResponse: content: application/json: schema: - $ref: "#/components/schemas/ServeModelList" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ServeModelList" description: A response containing a list of `ServeModel` entities. ServeModelResponse: content: application/json: schema: - $ref: "#/components/schemas/ServeModel" + type: object + properties: + metadata: + type: object + description: Metadata about the response + data: + $ref: "#/components/schemas/ServeModel" description: A response containing a `ServeModel` entity. parameters: modelRegistryName: diff --git a/clients/ui/docker-compose.yaml b/clients/ui/docker-compose.yaml index 6c5f4bd74..7fbc2c8ca 100644 --- a/clients/ui/docker-compose.yaml +++ b/clients/ui/docker-compose.yaml @@ -5,7 +5,7 @@ services: ports: - 8080:8080 environment: - API_URL: http://model-registry-bff:4001 + API_URL: http://model-registry-bff:4000 networks: - model_registry depends_on: @@ -15,6 +15,7 @@ services: container_name: model-registry-bff command: - "--mock-k8s-client=true" + - "--mock-mr-client=true" networks: - model_registry diff --git a/clients/ui/frontend/Dockerfile b/clients/ui/frontend/Dockerfile index 0e787fdee..c25a2b1c6 100644 --- a/clients/ui/frontend/Dockerfile +++ b/clients/ui/frontend/Dockerfile @@ -10,7 +10,7 @@ RUN npm run build FROM nginxinc/nginx-unprivileged -ENV API_URL="http://localhost:4001" +ENV API_URL="http://localhost:4000" ENV NGINX_ENVSUBST_FILTER="API_URL" COPY --from=build-stage /usr/src/app/dist/ "/usr/share/nginx/html" diff --git a/clients/ui/frontend/README.md b/clients/ui/frontend/README.md index c8f062d7d..63ca41ba7 100644 --- a/clients/ui/frontend/README.md +++ b/clients/ui/frontend/README.md @@ -7,7 +7,7 @@ The Kubeflow Model Registry UI is a standalone web app for Kubeflow Model Registry. -## Contributing: +## Contributing Individual bug fixes are welcome, it is recommended that you create a bug [issue] at the same time to describe the fix you're applying. If you are unsure how best to solve it, start with the issue and note your desire to contribute. diff --git a/clients/ui/frontend/docs/dev-setup.md b/clients/ui/frontend/docs/dev-setup.md index 327a40577..2fe6e9653 100644 --- a/clients/ui/frontend/docs/dev-setup.md +++ b/clients/ui/frontend/docs/dev-setup.md @@ -8,10 +8,6 @@ This project requires the following tools to be installed on your system: - Node recommended version -> `20.17.0` - NPM recommended version -> `10.8.2` -### Additional tooling - -[TBD] - ## Development 1. Clone the repository diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/pages/appChrome.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/pages/appChrome.ts index 8d30c9a48..5d6afc32d 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/pages/appChrome.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/pages/appChrome.ts @@ -9,7 +9,7 @@ class AppChrome { cy.testA11y(); } - // TODO: implement when authorization is enabled + // TODO: [Auth-enablement] Uncomment once auth is enabled // shouldBeUnauthorized() { // cy.findByTestId('unauthorized-error'); // return this; diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/application.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/application.ts index 7b5de43ea..c6100d0cd 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/application.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/application.ts @@ -7,7 +7,7 @@ import type { Matcher, MatcherOptions as DTLMatcherOptions } from '@testing-libr declare global { namespace Cypress { interface Chainable { - // TODO: Uncomment when authorization is enabled + // TODO: [Auth-enablement] Uncomment once auth is enabled // /** // * Visits the URL and performs a login if necessary. // * Uses credentials supplied by environment variables if not provided. @@ -121,7 +121,7 @@ declare global { } } -// TODO: Uncomment when authorization is enabled +// TODO: [Auth-enablement] Uncomment once auth is enabled // Cypress.Commands.add('visitWithLogin', (url, user = TEST_USER) => { // if (Cypress.env('MOCK')) { // cy.visit(url); diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts index dc9940b24..e6cb531c3 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts @@ -205,35 +205,22 @@ describe('Model Registry core', () => { }); }); -// TODO: Enable when model registration is there -// describe('Register Model button', () => { -// it('Navigates to register page from empty state', () => { -// initIntercepts({ disableModelRegistryFeature: false, registeredModels: [] }); -// modelRegistry.visit(); -// modelRegistry.findRegisterModelButton().click(); -// cy.findByTestId('app-page-title').should('exist'); -// cy.findByTestId('app-page-title').contains('Register model'); -// cy.findByText('Model registry - modelregistry-sample').should('exist'); -// }); - -// it('Navigates to register page from table toolbar', () => { -// initIntercepts({ disableModelRegistryFeature: false }); -// modelRegistry.visit(); -// modelRegistry.findRegisterModelButton().click(); -// cy.findByTestId('app-page-title').should('exist'); -// cy.findByTestId('app-page-title').contains('Register model'); -// cy.findByText('Model registry - modelregistry-sample').should('exist'); -// }); - -// it('should be accessible for non-admin users', () => { -// asProjectEditUser(); -// initIntercepts({ -// disableModelRegistryFeature: false, -// allowed: false, -// }); - -// modelRegistry.visit(); -// modelRegistry.navigate(); -// modelRegistry.shouldModelRegistrySelectorExist(); -// }); -// }); +describe('Register Model button', () => { + it('Navigates to register page from empty state', () => { + initIntercepts({ registeredModels: [] }); + modelRegistry.visit(); + modelRegistry.findRegisterModelButton().click(); + cy.findByTestId('app-page-title').should('exist'); + cy.findByTestId('app-page-title').contains('Register model'); + cy.findByText('Model registry - modelregistry-sample').should('exist'); + }); + + it('Navigates to register page from table toolbar', () => { + initIntercepts({ registeredModels: [] }); + modelRegistry.visit(); + modelRegistry.findRegisterModelButton().click(); + cy.findByTestId('app-page-title').should('exist'); + cy.findByTestId('app-page-title').contains('Register model'); + cy.findByText('Model registry - modelregistry-sample').should('exist'); + }); +}); diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts index 3aa7f9c50..c3fd860e2 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts @@ -130,7 +130,7 @@ describe('Model Versions', () => { }); it('Model versions table', () => { - // TODO: Uncomment when we fix finding listbox items + // TODO: [Testing] Uncomment when we fix finding listbox items initIntercepts({ modelRegistries: [ diff --git a/clients/ui/frontend/src/app/App.tsx b/clients/ui/frontend/src/app/App.tsx index 430a9ff07..494ee459e 100644 --- a/clients/ui/frontend/src/app/App.tsx +++ b/clients/ui/frontend/src/app/App.tsx @@ -19,11 +19,11 @@ import { StackItem, } from '@patternfly/react-core'; import { BarsIcon } from '@patternfly/react-icons'; -import ToastNotifications from '~/components/ToastNotifications'; +import ToastNotifications from '~/shared/components/ToastNotifications'; +import { useSettings } from '~/shared/hooks/useSettings'; import NavSidebar from './NavSidebar'; import AppRoutes from './AppRoutes'; import { AppContext } from './AppContext'; -import { useSettings } from './useSettings'; import { ModelRegistrySelectorContextProvider } from './context/ModelRegistrySelectorContext'; const App: React.FC = () => { @@ -62,7 +62,7 @@ const App: React.FC = () => {