From ebc6ee306ca2ee120f37b37550c06f87aace0f48 Mon Sep 17 00:00:00 2001 From: Lucas Fernandez Date: Tue, 8 Oct 2024 14:09:07 +0200 Subject: [PATCH 01/11] Add archived model to mocks (#467) Signed-off-by: lucferbux --- .../mocks/model_registry_client_mock.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/clients/ui/bff/internal/mocks/model_registry_client_mock.go b/clients/ui/bff/internal/mocks/model_registry_client_mock.go index 1081bcc6..9a35e331 100644 --- a/clients/ui/bff/internal/mocks/model_registry_client_mock.go +++ b/clients/ui/bff/internal/mocks/model_registry_client_mock.go @@ -1,11 +1,12 @@ package mocks import ( + "log/slog" + "net/url" + "github.com/kubeflow/model-registry/pkg/openapi" "github.com/kubeflow/model-registry/ui/bff/internal/integrations" "github.com/stretchr/testify/mock" - "log/slog" - "net/url" ) type ModelRegistryClientMock struct { @@ -26,7 +27,11 @@ func (m *ModelRegistryClientMock) CreateRegisteredModel(_ integrations.HTTPClien return &mockData, nil } -func (m *ModelRegistryClientMock) GetRegisteredModel(_ integrations.HTTPClientInterface, _ string) (*openapi.RegisteredModel, error) { +func (m *ModelRegistryClientMock) GetRegisteredModel(_ integrations.HTTPClientInterface, id string) (*openapi.RegisteredModel, error) { + if id == "3" { + mockData := GetRegisteredModelMocks()[2] + return &mockData, nil + } mockData := GetRegisteredModelMocks()[0] return &mockData, nil } @@ -36,7 +41,12 @@ func (m *ModelRegistryClientMock) UpdateRegisteredModel(_ integrations.HTTPClien return &mockData, nil } -func (m *ModelRegistryClientMock) GetModelVersion(_ integrations.HTTPClientInterface, _ string) (*openapi.ModelVersion, error) { +func (m *ModelRegistryClientMock) GetModelVersion(_ integrations.HTTPClientInterface, id string) (*openapi.ModelVersion, error) { + if id == "3" { + mockData := GetModelVersionMocks()[2] + return &mockData, nil + } + mockData := GetModelVersionMocks()[0] return &mockData, nil } From 222194a626dda37540f0fb8d68a75ce3ea9d6062 Mon Sep 17 00:00:00 2001 From: Griffin Sullivan <48397354+Griffin-Sullivan@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:03:08 -0400 Subject: [PATCH 02/11] Add GitHub Action for building and pushing UI and BFF images (#446) Signed-off-by: Griffin-Sullivan --- .../workflows/build-and-push-ui-images.yml | 65 +++++++++++++++++++ Makefile | 17 ++++- clients/ui/manifests/base/kustomization.yaml | 4 +- 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/build-and-push-ui-images.yml diff --git a/.github/workflows/build-and-push-ui-images.yml b/.github/workflows/build-and-push-ui-images.yml new file mode 100644 index 00000000..b8c0d972 --- /dev/null +++ b/.github/workflows/build-and-push-ui-images.yml @@ -0,0 +1,65 @@ +name: Build and Push UI and BFF Images +on: + push: + branches: + - 'main' + tags: + - 'v*' + paths: + - 'clients/ui/**' +env: + IMG_ORG: kubeflow + IMG_UI_REPO: model-registry-ui + IMG_BFF_REPO: model-registry-bff + DOCKER_USER: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKER_PWD: ${{ secrets.DOCKERHUB_TOKEN }} + PUSH_IMAGE: true +jobs: + build-image: + runs-on: ubuntu-latest + steps: + # Assign context variable for various action contexts (main, CI) + - name: Assigning main context + if: github.head_ref == '' && github.ref == 'refs/heads/main' + run: echo "BUILD_CONTEXT=main" >> $GITHUB_ENV + # checkout branch + - uses: actions/checkout@v4 + # set image version + - name: Set main-branch environment + if: env.BUILD_CONTEXT == 'main' + run: | + commit_sha=${{ github.event.after }} + tag=main-${commit_sha:0:7} + echo "VERSION=${tag}" >> $GITHUB_ENV + - name: Build and Push UI Image + shell: bash + env: + IMG_REPO: ${{ env.IMG_UI_REPO }} + run: ./scripts/build_deploy.sh + - name: Build and Push BFF Image + shell: bash + env: + IMG_REPO: ${{ env.IMG_BFF_REPO }} + run: ./scripts/build_deploy.sh + - name: Tag Latest UI Image + if: env.BUILD_CONTEXT == 'main' + shell: bash + env: + IMG_REPO: ${{ env.IMG_UI_REPO }} + IMG: ${{ env.IMG_ORG }}/${{ env.IMG_UI_REPO }} + BUILD_IMAGE: false # image is already built in "Build and Push UI Image" step + run: | + docker tag ${{ env.IMG }}:$VERSION ${{ env.IMG }}:latest + # BUILD_IMAGE=false skip the build, just push the tag made above + VERSION=latest ./scripts/build_deploy.sh + - name: Tag Latest BFF Image + if: env.BUILD_CONTEXT == 'main' + shell: bash + env: + IMG_REPO: ${{ env.IMG_BFF_REPO }} + IMG: ${{ env.IMG_ORG }}/${{ env.IMG_BFF_REPO }} + BUILD_IMAGE: false # image is already built in "Build and Push BFF Image" step + run: | + docker tag ${{ env.IMG }}:$VERSION ${{ env.IMG }}:latest + # BUILD_IMAGE=false skip the build, just push the tag made above + VERSION=latest ./scripts/build_deploy.sh \ No newline at end of file diff --git a/Makefile b/Makefile index 3081c1d0..72204844 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) PROJECT_PATH := $(patsubst %/,%,$(dir $(MKFILE_PATH))) PROJECT_BIN := $(PROJECT_PATH)/bin GO ?= "$(shell which go)" +BFF_PATH := $(PROJECT_PATH)/clients/ui/bff +UI_PATH := $(PROJECT_PATH)/clients/ui/frontend # add tools bin directory PATH := $(PROJECT_BIN):$(PATH) @@ -21,6 +23,8 @@ IMG_ORG ?= kubeflow IMG_VERSION ?= main # container image repository IMG_REPO ?= model-registry +# container image build path +BUILD_PATH ?= . # container image ifdef IMG_REGISTRY IMG := ${IMG_REGISTRY}/${IMG_ORG}/${IMG_REPO} @@ -28,6 +32,17 @@ else IMG := ${IMG_ORG}/${IMG_REPO} endif +# Change Dockerfile path depending on IMG_REPO +ifeq ($(IMG_REPO),model-registry-ui) + DOCKERFILE := $(UI_PATH)/Dockerfile + BUILD_PATH := $(UI_PATH) +endif + +ifeq ($(IMG_REPO),model-registry-bff) + DOCKERFILE := $(BFF_PATH)/Dockerfile + BUILD_PATH := $(BFF_PATH) +endif + model-registry: build # clean the ml-metadata protos and trigger a fresh new build which downloads @@ -216,7 +231,7 @@ endif # build docker image .PHONY: image/build image/build: - ${DOCKER} build . -f ${DOCKERFILE} -t ${IMG}:$(IMG_VERSION) + ${DOCKER} build ${BUILD_PATH} -f ${DOCKERFILE} -t ${IMG}:$(IMG_VERSION) # build docker image using buildx # PLATFORMS defines the target platforms for the model registry image be built to provide support to multiple diff --git a/clients/ui/manifests/base/kustomization.yaml b/clients/ui/manifests/base/kustomization.yaml index 7a3e3676..4c9472a1 100644 --- a/clients/ui/manifests/base/kustomization.yaml +++ b/clients/ui/manifests/base/kustomization.yaml @@ -10,6 +10,6 @@ resources: images: - name: model-registry-ui-image - newName: quay.io/gsulliva/mr-ui:latest + newName: kubeflow/model-registry-ui:latest - name: model-registry-bff-image - newName: quay.io/gsulliva/mr-bff:latest + newName: kubeflow/model-registry-bff:latest From e6800768321671e270da00fc1ce24f80be01f4ec Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Tue, 8 Oct 2024 10:06:08 -0400 Subject: [PATCH 03/11] Fix UI Bugs for Labels (#466) Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> fix chips --- clients/ui/frontend/src/style/MUI-theme.scss | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/clients/ui/frontend/src/style/MUI-theme.scss b/clients/ui/frontend/src/style/MUI-theme.scss index c8bf4269..1557b661 100644 --- a/clients/ui/frontend/src/style/MUI-theme.scss +++ b/clients/ui/frontend/src/style/MUI-theme.scss @@ -83,7 +83,7 @@ --mui-spacing-4px: calc(0.5 * var(--mui-spacing)); - --mui-spacing-8px: calc(0.5 * var(--mui-spacing)); + --mui-spacing-8px: var(--mui-spacing); --mui-spacing-16px: calc(2 * var(--mui-spacing)); @@ -390,6 +390,19 @@ --pf-v6-c-label--PaddingInlineEnd: 0; height: 24px; } +.pf-v6-c-label.pf-m-overflow { + border: 1px solid var(--mui-palette-grey-400); + + .pf-v6-c-label__text { + color: var(--mui-palette-common-black); + padding: none; + } +} + +.pf-v6-c-label.pf-m-filled .pf-v6-c-label__actions .pf-v6-c-button { + margin: 0px 5px 0px -6px; + --pf-v6-c-button__icon--Color: var(--mui-palette-common-white); +} .pf-v6-c-label__text { padding-right: var(--mui-spacing-8px); From 661cb254a7f3f887ee56ce08c2a465925264b328 Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:02:09 -0400 Subject: [PATCH 04/11] Apply MUI theming to Register Model Form (#451) Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> fix tests Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> add fieldset to custom components fix spacing issue with helper text Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> remove comment Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> fixes for text area Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> format Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> add model description fix Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> create reusable fieldset component Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> move fieldset to components Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> add prop for className Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> lint Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> fix import warnings fix TS error with FormFieldset.tsx Signed-off-by: Jenny <32821331+jenny-s51@users.noreply.github.com> fix import order errors --- .../PrefilledModelRegistryField.tsx | 10 +- .../screens/RegisterModel/RegisterModel.tsx | 59 +++- .../screens/RegisterModel/RegisterVersion.tsx | 1 - .../RegisterModel/RegisteredModelSelector.tsx | 26 +- .../RegistrationCommonFormSections.tsx | 251 ++++++++------ .../RegisteredModelListView.tsx | 34 +- .../screens/components/FormFieldset.tsx | 20 ++ clients/ui/frontend/src/style/MUI-theme.scss | 320 +++++++++++++++--- 8 files changed, 531 insertions(+), 190 deletions(-) create mode 100644 clients/ui/frontend/src/app/pages/modelRegistry/screens/components/FormFieldset.tsx diff --git a/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/PrefilledModelRegistryField.tsx b/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/PrefilledModelRegistryField.tsx index 980da8d3..1261a9df 100644 --- a/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/PrefilledModelRegistryField.tsx +++ b/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/PrefilledModelRegistryField.tsx @@ -1,13 +1,19 @@ import React from 'react'; import { FormGroup, TextInput } from '@patternfly/react-core'; +import FormFieldset from '~/app/pages/modelRegistry/screens/components/FormFieldset'; type PrefilledModelRegistryFieldProps = { mrName?: string; }; const PrefilledModelRegistryField: React.FC = ({ mrName }) => ( - - + + + } + field="Model Registry" + /> ); diff --git a/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/RegisterModel.tsx b/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/RegisterModel.tsx index c6cffb9d..b9bf9764 100644 --- a/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/RegisterModel.tsx +++ b/clients/ui/frontend/src/app/pages/modelRegistry/screens/RegisterModel/RegisterModel.tsx @@ -13,6 +13,7 @@ import { import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; import { useParams, useNavigate } from 'react-router'; import { Link } from 'react-router-dom'; +import FormFieldset from '~/app/pages/modelRegistry/screens/components/FormFieldset'; import FormSection from '~/app/components/pf-overrides/FormSection'; import ApplicationsPage from '~/app/components/ApplicationsPage'; import { modelRegistryUrl, registeredModelUrl } from '~/app/pages/modelRegistry/screens/routeUtils'; @@ -21,7 +22,6 @@ import { useRegisterModelData, RegistrationCommonFormData } from './useRegisterM import { isRegisterModelSubmitDisabled, registerModel } from './utils'; import { useRegistrationCommonState } from './useRegistrationCommonState'; import RegistrationCommonFormSections from './RegistrationCommonFormSections'; -import PrefilledModelRegistryField from './PrefilledModelRegistryField'; import RegistrationFormFooter from './RegistrationFormFooter'; const RegisterModel: React.FC = () => { @@ -42,6 +42,31 @@ const RegisterModel: React.FC = () => { }); const onCancel = () => navigate(modelRegistryUrl(mrName)); + const modelRegistryInput = ( + + ); + + const modelNameInput = ( + setData('modelName', value)} + /> + ); + + const modelDescriptionInput = ( +