Coder Social home page Coder Social logo

tackle2-ui's Introduction

tackle2-ui

Operator Repository on Quay License contributions welcome

Konveyor UI component

Build and Test Status

branch last merge CI last merge image build nightly CI
main CI (repo level) Multiple Architecture Image Build Nightly CI (repo level @main)
release-0.4 CI (repo level) Multiple Architecture Image Build CI (repo level)
release-0.3 CI (repo level) Multiple Architecture Image Build CI (repo level)
branch last merge e2e CI nightly e2e CI
main CI (global konveyor CI) Nightly CI (global konveyor CI @main)
release-0.4 CI (global konveyor CI) CI (global konveyor CI)
release-0.3 CI (global konveyor CI) CI (global konveyor CI)

Development

Prerequisites

  • NodeJS >= 16.x
  • minikube (optional): setup your local minikube instance with your container manager of choice. (Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation.)

Installation

To get started, clone the repo to your development workstation and install the required dependencies locally with NPM.

git clone https://github.com/konveyor/tackle2-ui
cd tackle2-ui
npm install

Quick start

With an existing Tackle2 environment available, one can start a locally served tackle2-ui instance with:

npm run start:dev

Tackle2 environment setup

With the UI project setup out of the way, you can now begin setting up you local Tackle2 dev environment. The preferred local development option is to setup a minikube instance. Alternatively, for information on general Kubernetes installation refer to Tackle2 operator readme file.

Minikube setup

Minikube implements a local Kubernetes cluster on macOS, Linux, and Windows. See the minikube getting started guide here.

All you need to run minikube is Docker (or similarly compatible) container or a Virtual Machine environment.

By default, Minikube uses a driver with 6,000 MB of memory and 2 CPUs. This is not enough to run all the services, so we need to increase the allocated memory. In our experience, 10 GB of memory and 4 CPUs is fine:

$ minikube config set memory 10240
$ minikube config set cpus 4

Note: Depending on your driver, administrator access may be required. Common choices include Docker for container-based virtualization and KVM for hardware-assisted virtualization on Linux systems. If you're not sure which driver is best for you or if you're encountering compatibility issues, Minikube also supports auto-selecting a driver based on your system's capabilities and installed software.

From a terminal run:

$ minikube start --addons=dashboard --addons=ingress

Note: We need to enable the dashboard and ingress addons. The dashboard addon installs the dashboard service that exposes the Kubernetes objects in a user interface. The ingress addon allows us to create Ingress CRs to expose the Tackle UI and Tackle Hub API.

Since the olm addon is disabled until OLM issue 2534 is resolved we need to install the OLM manually i.e. for version v0.28.0 we can use:

curl -L https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.28.0/install.sh -o install.sh
chmod +x install.sh
./install.sh v0.28.0

See also official Konveyor instructions for Provisioning Minikube.

Configuring kubectl for minikube

You will need kubectl on your PATH and configured to control minikube in order to proceed. There are two ways to set this up:

  1. Install kubectl yourself

    If you already have the kubectl CLI tool installed and available on your PATH, the minikube start command should configure it to control the minikube cluster. You should see the following message when minikube starts if this worked correctly:

    πŸ„  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
    
  2. Use a shell alias for minikube's built-in kubectl

    Minikube provides its own internal kubectl which you can use by running minikube kubectl -- followed by your CLI arguments. If you want to use the built-in minikube kubectl as the kubectl on your PATH, you can set a shell alias. The following example shows how to do it for Bash on Fedora 35.

    $ mkdir -p ~/.bashrc.d
    $ cat << EOF > ~/.bashrc.d/minikube
    alias kubectl="minikube kubectl --"
    EOF
    $ source ~/.bashrc

Installing the Konveyor operator

Follow the official instructions for Installing Konveyor Operator

Alternative 1, use the script hack/setup-operator.sh. It is a local variation of the script from the operator that still allows overriding portions of the Tackle CR with environment variables.

Alternative 2, the konveyor/operator git repository provides a script to install Tackle locally using kubectl. You can inspect its source here. This script creates the konveyor-tackle namespace, CatalogSource, OperatorGroup, Subscription and Tackle CR, then waits for deployments to be ready.

Customizing the install script (optional)

The install script provides optional environment variables you can use to customize the images and features used. See the source of the script for all available variables.

For example, if you wish to run tackle with keycloak authentication enabled, export the following variable before running the install script:

$ export AUTH_REQUIRED=true

Running the install script

Before proceeding, if you are on macOS you will need to use Homebrew to install the coreutils package:

$ brew install coreutils

To run the install script (requires kubectl on your PATH configured for minikube):

$ curl https://raw.githubusercontent.com/konveyor/operator/main/hack/install-tackle.sh | bash

Alternatively, you can clone the konveyor/operator git repository and run ./hack/install-tackle.sh from your clone, or you can execute its commands manually.

⚠️ Note: While CRDs are being established, you may see the script output NotFound errors. You can safely ignore these. The script will wait 30 seconds to check for the CRD again before proceeding.

The installation is complete when the script outputs "condition met" messages and terminates.

Start your local development server

Now that your environment is ready, navigate to your installed tackle-ui directory and run your development server:

$ cd tackle2-ui
$ npm run start:dev

Understanding the local development environment

Tackle2 runs in a Kubernetes compatible environment (i.e. Openshift, Kubernetes or minikube) and is usually deployed with Tackle2 Operator (OLM). Although the UI pod has access to tackle2 APIs from within the cluster, the UI can also be executed outside the cluster and access Tackle APIs endpoints by proxy.

The React and Patternfly based UI is composed of web pages served by an http server with proxy capabilities.

  • In production mode, Express (Node.js) plays the role of both UI server and proxy server (using http-proxy-middleware). Everything is served on port 8080. The /auth and /hub routes are proxied to their services. All other routes serve the UI bundle where they are handled by react-router.

  • In development mode, webpack-dev-server plays the role of UI server and Express plays the role of proxy server only. This allows webpack-dev-server to provide development features such as hot reload. The webpack-dev-server serves the UI on port 9000. The /auth and /hub routes are forwarded to port 8080 for Express to handle.

The Express server/src/setupProxy.js proxies use the environment variables TACKLE_HUB_URL and SSO_SERVER_URL to define the backend endpoints:

  • If the Tackle Hub variable TACKLE_HUB_URL is not defined, the URL http://localhost:9002 is used by default.

  • If the Tackle Keycloak (SSO) variable SSO_SERVER_URL is not defined, the URL http://localhost:9001 is used by default.

Running the UI outside the cluster

To enable running the UI outside the cluster, port forwardings must be activated to route the Tackle Keycloak (SSO) and Tackle Hub requests to the services on the cluster. Use the script npm run port-forward to easily start the forwards. The script npm run start:dev will also setup port forwarding to all tackle2 services concurrently with starting the dev server.

To manually setup the kubectl port forwards, open a terminal and run each following command separately:

$ kubectl port-forward svc/tackle-keycloak-sso -n konveyor-tackle 9001:8080
$ kubectl port-forward svc/tackle-hub -n konveyor-tackle 9002:8080

Note: The npm run port-forward or kubectl port-forward commands need to remain running for the ports to be available.

Accessing the Kubernetes dashboard

We may need to access the dashboard, either simply to see what's happening under the hood, or to troubleshoot an issue. The dashboard addon is enabled in the default in recommended minikube start command in the Minikube setup section.

There are two ways to setup access to the dashboard.

First, we can use the minikube dashboard command. Use to following to open on an explicit port and only show the URL instead of opening the default browser directly:

$ minikube dashboard --port=18080 --url=true

Second, we can use the kubectl port-forward command to enable access to the dashboard:

$ kubectl port-forward svc/kubernetes-dashboard -n kubernetes-dashboard 30090:80

We can now access the minikube dashboard on http://localhost:30090

Troubleshooting

Note - The steps described are executed on a Fedora 38 workstation, but will likely work on any recent Linux distribution.

  • For minikube setups that rely on virtualization, the only prerequisites are to enable virtualization extensions in the BIOS/EFI of the machine, to install libvirt and to add our user to the libvirt group.

  • Ensure that your minikube installation directory is available in your $PATH environment variable. This is usually /usr/local/bin/ or something similar depending on your OS of choice.

  • The following command gives us the IP address assigned to the node created by Minikube. It's used when interacting with tackle UI image installed on the minikube cluster.

$ minikube ip
192.168.39.23

Pull Request (PR) Process

Please read the Pull Request (PR) Process section of the Konveyor versioning and branching doc for more information.

File Naming Conventions

  • Use kebab-case for file names.
  • The root page/parent level components are placed directly in their respective directories.
  • Presentation layer components are placed within the components/ subdirectory of the parent component.

Contributing

We welcome contributions to this project! If you're interested in contributing, please read the konveyor/community CONTRIBUTING doc for more information on how to get started.

Code of Conduct

Refer to Konveyor's Code of Conduct page

tackle2-ui's People

Contributors

abrugaro avatar aufi avatar avivtur avatar dependabot[bot] avatar djzager avatar fabianvf avatar fbladilo avatar gildub avatar gitdallas avatar ibolton336 avatar jmontleon avatar jortel avatar jwmatthews avatar kpunwatk avatar mansam avatar mguetta1 avatar mturley avatar rszwajko avatar sarthaksarthak9 avatar savitharaghunathan avatar sjd78 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tackle2-ui's Issues

Tasks filter breaking application status

image

  • the useFetchTasks filter assumes that there will be an addon field on the task object here. Currently the field is only present for admin tasks, so the filter is not working as expected.

Form field unique selectors: align on using `id` where possible, follow up to help fix QE tests

Related to #198. Ideally we can fix both together.

For rationale, see the "Accessibility and QE selectors" section at the bottom of the description in #404. The main conclusions there are:

  • We need a unique id attribute on each form input in order to provide accessible labels without redundant aria-label attributes
  • We should NOT use aria-label as a selector for QE tests since it is user-facing text that is subject to change or be removed (it is used by screen-readers for accessibility)
  • QE tests should use id selectors where possible and work with dev on what selector to use when id cannot be provided on a case-by-case basis. When this comes up it is likely a bug in PatternFly and we can provide a real id once that bug is addressed.

#404 included changes to support the above for the Proxy settings form and the Identity form (the Create/Edit Credential modal in the Admin view). That PR includes heavy refactoring that should not be backported to 2.1.x, but we should create a separate PR to backport matching id / aria-label changes to 2.1.2 once that release branch exists. We should then make sure we follow up to help transition relevant QE tests to use the new id selectors.

As more forms are refactored to use the new react-hook-form components, we will also be aligning their field attributes in a similar way, and any of those that are merged before 2.1.2 code freeze should also have their selector changes backported as part of this issue.

Session handling improvements

Currently , the cookie is being re-hydrated by react query every 5 seconds or so. This can be improved by relying on keycloaks internal token update functionality that gets triggered when any api request is fired via an axios interceptor. We can use this hook to update the cookie and handle any token expiry logic.

Also, the current token expires after 5 minutes. This can be lengthened to improve the experience when using 3rd party served html pages that rely on the cookie for authentication. These pages also need to redirect the user to /login once the token is expired given that the cookie is stale and not being refreshed due to a closed "main tackle tab".

Restore Typescript strict compiler rules

Tackle-ui (version 1.x) TS compiler was using the rule strict: 'true' which by default defines noImplicitAny to true (and alwaysStrict too).
The migration to tackle2-ui introduced by mistake the noImplicitAny": false rule to the TS compiler options.
This potentially opens the door for technical debt which would be very difficult to correct afterwards.
Effectively the legacy code (tackle-ui v1.x) is clean as it was using a de facto noImplicitAny.
Only handfuls of errors have been introduced and should be addressed as one of major point of using TS is to help have type safe guards.

Docs: Improve developer guide

Add updates to development.md to fill in missing knowledge gaps for:

  • Reverse proxy configuration
  • Additional supplemental documentation on legacy formik forms. Identify legacy components and identify upgrade paths to new RHF components. This is technical debt.

Analysis status improvements.

  • No loading indicator for freshly started analysis. Would be nice to have a visual indicator of an ongoing/running analysis
  • Analysis status does not change immediately after kicking off an analysis.
  • Warning/error status is a bit buried in the expanded view. Would be great to have a top level status for the analysis

Add datepicker for creating migration waves

The datepicker will involve some conditional logic:

"There are some considerations regarding the Start date and End date fields. First, the Start date date picker field won't show any dates in the past, as it makes no sense to create new migration waves happening before the present day. First day to be displayed, will be the present day, highlighted in light blue:

Image

The End date date picker field will show the start date day that was picked and will leave a light blue highlight between that and the selected end date day.

Image

Create new migration wave

  • Add a create new button at the top of the migration wave page
  • Add user interaction flow for open/closing modal for creating new wave
  • Add a new form for creating the migration wave
  • Form fields:
    • Name: Optional. String with the name of the wave.
    • Start date: Placeholder. See #575
    • End date: Placeholder. See #575
    • Stakeholders: Optional. Dropdown, multiple selection. Values will be the list of available stakeholders in the instance. Stakeholders to associate directly to the migration wave. When an application is assigned to a migration wave, all of its associated stakeholders get transitively associated to the wave. By associating them directly through this field, they will appear with no role in the Stakeholders compound expandable section.
    • Stakeholder Groups: Optional. Dropdown, multiple selection. Values will be the list of available stakeholder groups in the instance. Stakeholder groups to associate directly to the migration wave. By associating a Stakeholder Group to a migration wave through this field, all the associated stakeholders in the group will appear with no role in the Stakeholders compound expandable section.

Image

Add owner & contributor searchable dropdown fields to application form

Image

The application creation view will include two new fields:

  • Owner: Dropdown, single selection. The dropdown will include all available Stakeholders in the system. It would be good to make it searchable to avoid loading all stakeholders at once.

  • Contributors: Dropdown, multiple selection. The dropdown will include all available Stakeholders in the system. It would be good to make it searchable to avoid loading all stakeholders at once.

RBAC components: These fields will be disabled for all users other than PM & architect. The architect will have full RW permissions and the PM will be able to edit the fields.

Applications inventory analysis tab: warning about dropdownItems

This issue needs to be investigated and has been introduced by #133 and related #129.

Children and dropdownItems props have been provided. Only the dropdownItems prop items will be rendered [DropdownWithContext.js:24](webpack://tackle2-ui/node_modules/@patternfly/react-core/dist/esm/components/Dropdown/DropdownWithContext.js?f26b)

Add applications compound expandable section to migration waves table

Image

Application: Compound expandable section with a nested table that includes the list of applications assigned to the migration wave. Each row will have a kebab menu with just one option, "Remove", to remove the application belonging to the row from the list of assigned applications to the migration wave. Each row will include the following fields from the application:

  • Application name
  • Description
  • Business service
  • Owner
    NOTE: Open discussion on how to deal with n number of applications associated with m migration wave

Updated image with pagination:

Image

Sometimes selectors for DOM objects are not unique

Sometimes selectors for objects are not unique and UI automated tests can't figure out which object is needed.
Examples:,

  1. When configuring proxy - credentials selection both for HTTP and HTTPS are the same
  2. Perspective view droplist has all the same selectors as, for example, droplist when creating tags
    If I will find anything else - I will add them here as comments

Assess legacy tests usufulness

/qe contains legacy tests inherited from Tackle 1.

Those are redundant as unit tests for UI components are covered along the code with Unit Test Library and integration along with e2e tests are taken care by https://github.com/konveyor/tackle-ui-tests.

Before completely remove those test we need to assess its content to identify the ones to keep or not.

RBAC for JIRA integration

  • Setup proper roles / scopes for different users involved
  • Administrator
    • The administrator for the tool that has access to some application-wide configuration parameters that other users can consume but not change or browse. Example: Jira configuration, Jira Credentials.
  • Architect
    • A technical lead for the migration project that can create and modify applications and information related to it. The Architects don’t need to have access to sensitive information, but can consume it. Example: Create an issue from an application without knowing the credentials of a given Jira instance.

Applications inventory assessment tab: React Key warning

This needs to be investigated so we can address it. I appeared after PR#93.

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `Context.Consumer`. It was passed a child from ApplicationsTable. See https://reactjs.org/link/warning-keys for more information.
DropdownItem@webpack-internal:///./node_modules/@patternfly/react-core/dist/esm/components/Dropdown/DropdownItem.js:19:130
DropdownWithContext@webpack-internal:///./node_modules/@patternfly/react-core/dist/esm/components/Dropdown/DropdownWithContext.js:23:9
Dropdown@webpack-internal:///./node_modules/@patternfly/react-core/dist/esm/components/Dropdown/Dropdown.js:21:52
KebabDropdown@webpack-internal:///./src/app/shared/components/kebab-dropdown/kebab-dropdown.tsx:13:25
div
ToolbarItem@webpack-internal:///./node_modules/@patternfly/react-core/dist/esm/components/Toolbar/ToolbarItem.js:32:113
RBAC@webpack-internal:///./src/app/rbac.ts:18:30
div
ToolbarGroupWithRef@webpack-internal:///./node_modules/@patternfly/react-core/dist/esm/components/Toolbar/ToolbarGroup.js:24:1
div
...

Create instance

The administrator can create an instance by clicking the "Create instance" button. This will open a modal window with the following fields:

  • Instance name: String
  • URL: String
  • Instance type: Dropdown, single selection. Values:
    • Server
    • Data Center
    • Cloud
  • Credentials: Dropdown, single selection. Will display a list of all Jira credentials available on the system.
  • Enable insecure communication: Toggle.

There will be two buttons at the bottom of the modal window:

  • Save: Validates the input and creates a new instance.
  • Cancel: Exists the modal window. If any data has been entered, the system will ask for confirmation.

Image

No Typescript type check through building toolchain

Running "tsc -p tsconfig.json" shows errors not reported by ts-loader.
This is likely a combination of TranspileOnly = true option for ts-loader and legacy tsconfig.json compiler option noEmit = true.
The latter worked with babel but doesn't in the tackle v2 building toolchain.
As the type check is not reported to build, CI doesn't catch it either.

Filters refresh on navigation

  • It would be nice to store filter state between page navigation. When there are a large number of applications loaded in the application, it can be annoying to have to search / filter for the app you want to see every time you navigate to another page.

Some validation error messages are not using localization (`t()`)

This is present in most places we are using Yup's .test() method. Example:

"A business service with this name already exists. Please use a different name.",

These strings should be moved to the translation.json files and parameterized with t(). They should also not use the word "please" (see #211)

Applications: Foreign Key for tags create unnecessary burden

Replacing application tags field with an array of string instead of an array for tag references would provide more flexibility.

By decoupling tags would allow to delete tags whether they are used or not by applications.

A way to see it is like ink pads, one can remove an ink pad without having to remove the marked items.

See #94 for some details

Add tackle-test-generator addon to UI

Now that we have https://github.com/konveyor/tackle2-addon-test-generator we should update the UI to include this alongside assess/analyze. Something like:

1666983447

The data in a POST to /tasks looks like:

{
  "name": "Test Generator",
  "state": "Ready",
  "locator": "testgen",
  "addon": "testgen",
  "application": {
    "id": 1
  },
  "data": {
    "branch_name": "ftw", # (required) branch where changes should be stored
    "tkltest_config": {
      "general": {
        "test_directory": # (optional) where to store the tests
      },
      "generate": {
        "app_build_files": [ # (optional) build files to use
          "pom.xml"
        ],
        "target_class_list": [], # (optional)
        "excluded_class_list": [], # (optional)
        "time_limit": 30 # (optional)
      }
    }
  }
}
  • Branch name (json:branch_name) - name of the branch where the changes will be committed
  • Test Directory (json:test_directory) - where to put the generated tests

Add migration waves initial skeleton page & wire up navigation to new menu item

Image

  • Add the migration waves page

  • Add new migration waves sidebar menu item with RBAC

  • Create the migration waves table with the following columns:

    • Name: Name of the migration wave. This field is optional and could appear empty.
    • Start date: Start date for the migration wave.
    • End date: End date for the migration wave.
    • Application: Placeholder to start with. See #571
    • Contributors: Placeholder to start with. See #572

Add QE-specific tags to be used by QE instead of aria-labels

./integration/views/tags.view.ts:export const dropdownMenuToggle = "button[aria-label='Options menu']";
./integration/views/tags.view.ts:export const nameInput = "input[aria-label='name']";
./integration/views/tags.view.ts:export const rankInput = "input[aria-label='rank']";
./integration/views/tags.view.ts:export const tagTable = "table[aria-label='tag-table']";
./integration/views/tags.view.ts:export const tagMenuButton = "button[aria-label='Actions']";
./integration/views/credentials.view.ts:export const privatePassphraseInput = "input[aria-label='Private Key Passphrase']";
./integration/views/jobfunctions.view.ts:export const createJobfunctions = "button[aria-label=create-job-function]";
./integration/views/jobfunctions.view.ts:export const jobfunctionConfirmDelete = "button[aria-label=confirm]";
./integration/views/assessment.view.ts:export const continueButton = "button[aria-label=confirm]";
./integration/views/applicationinventory.view.ts:export const actionButton = "div > button[aria-label='Actions']";
./integration/views/applicationinventory.view.ts:export const closeForm = "button[aria-label='close']";
./integration/views/applicationinventory.view.ts:export const copy = "button[aria-label='copy']";
./integration/views/applicationinventory.view.ts:export const northdependenciesDropdownBtn = "button[aria-label='northbound-dependencies-toggle']";
./integration/views/applicationinventory.view.ts:export const southdependenciesDropdownBtn = "button[aria-label='southbound-dependencies-toggle']";
./integration/views/applicationinventory.view.ts:export const kebabMenu = "div > button[aria-label='Actions']";
./integration/views/reports.view.ts: "article > div > div > table[aria-label='main-table']";
./integration/views/reports.view.ts:export const identiFiedRisksTable = "article > div > div > div > table[aria-label='main-table']";
./integration/views/reports.view.ts:export const itemsPerPageToggleButton = "div > button[aria-label='Items per page']";
./integration/views/common.view.ts:export const itemsPerPageToggleButton = "button[aria-label='Items per page']";
./integration/views/common.view.ts:export const submitButton = "button[aria-label=submit]";
./integration/views/common.view.ts:export const cancelButton = "button[aria-label=cancel]";
./integration/views/common.view.ts:export const closeButton = "button[aria-label=Close]";
./integration/views/common.view.ts:export const confirmButton = "button[aria-label=confirm]";
./integration/views/common.view.ts:export const editButton = "button[aria-label=edit]";
./integration/views/common.view.ts:export const deleteButton = "button[aria-label=delete]";
./integration/views/common.view.ts:export const removeButton = "button[aria-label='Remove']";
./integration/views/common.view.ts:export const clearAllButton = "button[aria-label='Clear all']";
./integration/views/common.view.ts:export const itemsPerPageMenuOptions = "ul[aria-labelledby='pagination-id-toggle']";
./integration/views/common.view.ts:export const expandRow = "button[aria-label=Details]";
./integration/views/common.view.ts:export const successAlertMessage = "div[aria-label='Success Alert']";
./integration/views/common.view.ts:export const duplicateNameWarning = "div[aria-label='Danger Alert']";
./integration/views/common.view.ts:export const appTable = "table[aria-label='main-table']";
./integration/views/common.view.ts:export const searchButton = "button[aria-label='search button for search input']";
./integration/views/common.view.ts:export const nextPageButton = "button[aria-label='Go to next page']";
./integration/views/common.view.ts:export const prevPageButton = "button[aria-label='Go to previous page']";
./integration/views/common.view.ts:export const lastPageButton = "button[aria-label='Go to last page']";
./integration/views/common.view.ts:export const firstPageButton = "button[aria-label='Go to first page']";
./integration/views/common.view.ts:export const pageNumInput = "input[aria-label='Current page']";
./integration/views/common.view.ts:export const optionMenu = '[aria-label="Options menu"]';
./integration/views/common.view.ts:export const closeNotification = "button[aria-label='close-notification']";
./integration/views/analysis.view.ts:export const actionButton = "div > button[aria-label='Actions']";
./integration/views/analysis.view.ts: "main[aria-label='Application analysis content'] > div > div > div > div";
./integration/views/analysis.view.ts:export const sourceCredential = "input[aria-label='sourceCredentials']";
./integration/views/analysis.view.ts:export const mavenCredential = "input[aria-label='mavenSettings']";
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select']").click();
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select'] > span").should(
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select'] > span").should("contain", "9 selected");
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select']").click();
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select'] > span").should(
./integration/tests/developer/applicationinventory/assessment/copy_assessment/copy_assessment.test.ts: cy.get("button[aria-label='Select']").click();
./integration/models/developer/applicationinventory/assessment.ts: cy.react("p", { props: { "aria-label": "assess-application" } })
./integration/models/administrator/proxy/proxy.ts: inputText('[aria-label="excluded"]', fullList);
./integration/models/administrator/proxy/proxy.ts: clearInput('[aria-label="excluded"]');
./integration/models/administrator/credentials/credentialsProxy.ts: inputText("[aria-label='proxy-user']", this.username);
./integration/models/administrator/credentials/credentialsProxy.ts: validateValue("[aria-label='proxy-user']", username);
./integration/models/administrator/credentials/credentialsProxy.ts: inputText("[aria-label='proxy-password']", this.password);
./integration/models/administrator/credentials/credentialsSourceControlKey.ts: inputText("[aria-label='private-key-passphrase']", this.keyPassphrase);
./integration/models/administrator/credentials/credentialsSourceControlUsername.ts: inputText("[aria-label='user']", this.username);
./integration/models/administrator/credentials/credentialsSourceControlUsername.ts: inputText("[aria-label='password']", this.password);
./utils/utils.ts: cy.get("table[aria-label='main-table']", { timeout: 5 * SEC }).should(
./utils/utils.ts: if (!button["aria-label=Details"]) {
./utils/utils.ts: click('button[aria-label="Actions"]');

RouteWrapper: Address route warning

For supporting RBAC we wrapping routes with which is causing the following error:

Warning: You should not use <Route component> and <Route render> in the same route; <Route render> will be ignored 
Route@webpack-internal:///./node_modules/react-router/esm/react-router.js:448:29
RouteWrapper@webpack-internal:///./src/app/common/RouteWrapper.tsx:17:21

Add status compound expandable section to migration waves table

Status: Compound expandable section for the migration waves to reflect status data. This section is explained in depth in the related tackle-jira-integration enhancement.

A new compound expandable section is proposed for the migration waves to reflect status data. Rows on that section will include the following fields.

  • Application Name: Name for the given application.
  • Status: Status of the application in the issue manager. This field should load asynchronously to reflect the latest data on the issue manager.
  • Issue: Issue code in the issue manager with a link to the actual issue.

Linked to #564 & #563

At the top level of the compound expandable section, the aggregated status of the applications will be displayed in a text field with an icon. The business logic to manage both the aggregated and individual statuses is the following:

  • When applications are in the process of being imported to the issue manager, the aggregated status should be Creating Issues and the individual application status should be Creating Issue.

  • Once issues have been created, each issue should display their corresponding status on the issue manager. The aggregated status will display Issues Created if the current system date is previous to the Start Date for the wave, and In progress if the current system date is posterior to it.

  • When all issues associated to the applications in a wave have reached the universal closed state from the issue manager, the aggregated status will display Completed.

  • If there is any error creating an issue for an application, both its individual status and the aggregated status will display "Error".

Image

  • On Jira ecosystem, statuses do not have icons but colours.
  • Statuses are grouped into Status Catogories and every category has its own colour that is not configurable.
  • Right now Jira tools use the following Status Categories:
    • To-Do β†’ Initial status with colour Blue, e.g. OPEN
    • In Progress β†’ Intermediate status with colour Yellow, e.g. TESTING
    • Done β†’ Final status with colour Green, e.g. REJECTED
  • Any existing status or custom ones, that are created for the use in Jira workflows, will be mapped to one of these core categories and will take on the same colour.

Add project manager role to RBAC considerations

  • Update rbac.ts with expected Project Manager scopes
  • Make sure the Migration Waves nav menu item is route protected against all users but the Project Manager.
  • Check that all views are correctly protected with updates to Keycloak realm.

Note: You may need to login to the keycloak realm to create test users with the correct scopes/roles

Add stakeholders compound expandable section to migration waves table

Image

  • Stakeholders: Compound expandable section with a nested table that includes the list of stakeholders associated with a migration wave. This list will be automatically populated with all the owners and contributors to all the applications associated with the migration wave, and with any additional stakeholders that could have been associated directly to the migration wave on creation/edition or indirectly through the association of a determined stakeholder group. Just to clarify, if a stakeholder group is associated to a migration wave on creation/edition, all of its members will appear in this list. Each row will include the following fields:

  • Name

  • Job Function

  • Role: Owner, Contributor or empty if the stakeholder was associated directly or through a stakeholder group.

  • Email

  • Stakeholder groups: Groups the stakeholder belongs to.

Updated image with pagination:

Image

Allow single user mode

We need UI to honor the AUTH_REQUIRED pod environment variable , essentially this will cause Tackle to enable/disable keycloak auth and allow a user to just run as admin without auth.

When AUTH_REQUIRED is set (false) at the operator level keycloak will not be deployed , so environment variables SSO_* should not be required when AUTH_REQUIRED is set to false.

Also , for naming consistency the SSO_* UI env variables should match what the hub is using :

            - name: KEYCLOAK_REALM
              value: "{{ keycloak_sso_realm }}"
            - name: KEYCLOAK_HOST
              value: "{{ keycloak_sso_host }}"
            - name: KEYCLOAK_CLIENT_ID
              value: "{{ keycloak_sso_hub_client_id }}"
            - name: KEYCLOAK_CLIENT_SECRET
              valueFrom:
                secretKeyRef:
                  name: "{{ hub_secret_name }}"
                  key: keycloak_client_secret

For reference also see : konveyor/operator#33

Create task management page

It would be really helpful for the UX of tackle if there were a page dedicated to viewing all Tasks in the hub and expose some basic information like:

  • The application associated with the task
  • The addon being run
  • The secret associated with the task (ie. data for the addon)
  • (maybe) the Volume buckets (application/addon)
  • (Most importantly) the status of the task

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.