diff --git a/package-lock.json b/package-lock.json index 01938014c..297fadd1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0", + "version": "1.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0", + "version": "1.14.0", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index a10088e67..198fe2859 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0", + "version": "1.14.0", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", diff --git a/src/Assets/IconV2/ic-amazon-eks.svg b/src/Assets/IconV2/ic-amazon-eks.svg new file mode 100644 index 000000000..ca6d19c47 --- /dev/null +++ b/src/Assets/IconV2/ic-amazon-eks.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Assets/IconV2/ic-arrow-square-out.svg b/src/Assets/IconV2/ic-arrow-square-out.svg new file mode 100644 index 000000000..0cf743643 --- /dev/null +++ b/src/Assets/IconV2/ic-arrow-square-out.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-azure-aks.svg b/src/Assets/IconV2/ic-azure-aks.svg new file mode 100644 index 000000000..34b9e4d64 --- /dev/null +++ b/src/Assets/IconV2/ic-azure-aks.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Assets/IconV2/ic-caret-down-small.svg b/src/Assets/IconV2/ic-caret-down-small.svg new file mode 100644 index 000000000..9cd3df6fe --- /dev/null +++ b/src/Assets/IconV2/ic-caret-down-small.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-caret-right.svg b/src/Assets/IconV2/ic-caret-right.svg new file mode 100644 index 000000000..3a48b9552 --- /dev/null +++ b/src/Assets/IconV2/ic-caret-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-chat-circle-online.svg b/src/Assets/IconV2/ic-chat-circle-online.svg new file mode 100644 index 000000000..77560f3b4 --- /dev/null +++ b/src/Assets/IconV2/ic-chat-circle-online.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-cloud-vms.svg b/src/Assets/IconV2/ic-cloud-vms.svg new file mode 100644 index 000000000..a713f02ad --- /dev/null +++ b/src/Assets/IconV2/ic-cloud-vms.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Assets/IconV2/ic-cluster.svg b/src/Assets/IconV2/ic-cluster.svg new file mode 100644 index 000000000..f6aea37fd --- /dev/null +++ b/src/Assets/IconV2/ic-cluster.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-delete-dots.svg b/src/Assets/IconV2/ic-delete-dots.svg new file mode 100644 index 000000000..eba902e79 --- /dev/null +++ b/src/Assets/IconV2/ic-delete-dots.svg @@ -0,0 +1,62 @@ + + + + + + + diff --git a/src/Assets/IconV2/ic-disconnect.svg b/src/Assets/IconV2/ic-disconnect.svg new file mode 100644 index 000000000..b4d32e886 --- /dev/null +++ b/src/Assets/IconV2/ic-disconnect.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-discord-fill.svg b/src/Assets/IconV2/ic-discord-fill.svg new file mode 100644 index 000000000..2e3bc9aea --- /dev/null +++ b/src/Assets/IconV2/ic-discord-fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-edit.svg b/src/Assets/IconV2/ic-edit.svg new file mode 100644 index 000000000..2f3fcf52e --- /dev/null +++ b/src/Assets/IconV2/ic-edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-enterprise-feat.svg b/src/Assets/IconV2/ic-enterprise-feat.svg new file mode 100644 index 000000000..f80863f34 --- /dev/null +++ b/src/Assets/IconV2/ic-enterprise-feat.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-enterprise-tag.svg b/src/Assets/IconV2/ic-enterprise-tag.svg new file mode 100644 index 000000000..8be0fb147 --- /dev/null +++ b/src/Assets/IconV2/ic-enterprise-tag.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Assets/IconV2/ic-expand-right-sm.svg b/src/Assets/IconV2/ic-expand-right-sm.svg new file mode 100644 index 000000000..d9240b212 --- /dev/null +++ b/src/Assets/IconV2/ic-expand-right-sm.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-expand-sm.svg b/src/Assets/IconV2/ic-expand-sm.svg new file mode 100644 index 000000000..8c5411a7c --- /dev/null +++ b/src/Assets/IconV2/ic-expand-sm.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-file-edit.svg b/src/Assets/IconV2/ic-file-edit.svg new file mode 100644 index 000000000..a4fa313ce --- /dev/null +++ b/src/Assets/IconV2/ic-file-edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-file.svg b/src/Assets/IconV2/ic-file.svg new file mode 100644 index 000000000..8aec25d57 --- /dev/null +++ b/src/Assets/IconV2/ic-file.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-files.svg b/src/Assets/IconV2/ic-files.svg new file mode 100644 index 000000000..b1ba9f862 --- /dev/null +++ b/src/Assets/IconV2/ic-files.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-gift-gradient.svg b/src/Assets/IconV2/ic-gift-gradient.svg new file mode 100644 index 000000000..a738c1fd6 --- /dev/null +++ b/src/Assets/IconV2/ic-gift-gradient.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Assets/IconV2/ic-gift.svg b/src/Assets/IconV2/ic-gift.svg new file mode 100644 index 000000000..5aea477d9 --- /dev/null +++ b/src/Assets/IconV2/ic-gift.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-gitlab.svg b/src/Assets/IconV2/ic-gitlab.svg index ae6ed4f8c..1b4df0aaa 100644 --- a/src/Assets/IconV2/ic-gitlab.svg +++ b/src/Assets/IconV2/ic-gitlab.svg @@ -16,16 +16,16 @@ - + - - - - - - - - + + + + + + + + diff --git a/src/Assets/IconV2/ic-google-gke.svg b/src/Assets/IconV2/ic-google-gke.svg new file mode 100644 index 000000000..89920c7ce --- /dev/null +++ b/src/Assets/IconV2/ic-google-gke.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Assets/IconV2/ic-install.svg b/src/Assets/IconV2/ic-install.svg new file mode 100644 index 000000000..dedf568da --- /dev/null +++ b/src/Assets/IconV2/ic-install.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-k3s.svg b/src/Assets/IconV2/ic-k3s.svg new file mode 100644 index 000000000..3b55449c4 --- /dev/null +++ b/src/Assets/IconV2/ic-k3s.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-kind.svg b/src/Assets/IconV2/ic-kind.svg new file mode 100644 index 000000000..0d964b143 --- /dev/null +++ b/src/Assets/IconV2/ic-kind.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Assets/IconV2/ic-laptop.svg b/src/Assets/IconV2/ic-laptop.svg new file mode 100644 index 000000000..c8077e38c --- /dev/null +++ b/src/Assets/IconV2/ic-laptop.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-login-devtron-logo.svg b/src/Assets/IconV2/ic-login-devtron-logo.svg deleted file mode 100644 index 0c054d6e6..000000000 --- a/src/Assets/IconV2/ic-login-devtron-logo.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/src/Assets/IconV2/ic-megaphone-left.svg b/src/Assets/IconV2/ic-megaphone-left.svg new file mode 100644 index 000000000..48001f96b --- /dev/null +++ b/src/Assets/IconV2/ic-megaphone-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-megaphone-right.svg b/src/Assets/IconV2/ic-megaphone-right.svg new file mode 100644 index 000000000..7d9a151f4 --- /dev/null +++ b/src/Assets/IconV2/ic-megaphone-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-minikube.svg b/src/Assets/IconV2/ic-minikube.svg new file mode 100644 index 000000000..c1b2027d8 --- /dev/null +++ b/src/Assets/IconV2/ic-minikube.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Assets/IconV2/ic-mobile.svg b/src/Assets/IconV2/ic-mobile.svg new file mode 100644 index 000000000..5329e48d5 --- /dev/null +++ b/src/Assets/IconV2/ic-mobile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-path.svg b/src/Assets/IconV2/ic-path.svg new file mode 100644 index 000000000..5bb3ef197 --- /dev/null +++ b/src/Assets/IconV2/ic-path.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-sparkle-color.svg b/src/Assets/IconV2/ic-sparkle-color.svg new file mode 100644 index 000000000..a2aa5c5d3 --- /dev/null +++ b/src/Assets/IconV2/ic-sparkle-color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-terminal.svg b/src/Assets/IconV2/ic-terminal.svg new file mode 100644 index 000000000..0ebbdcb7c --- /dev/null +++ b/src/Assets/IconV2/ic-terminal.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-thermometer.svg b/src/Assets/IconV2/ic-thermometer.svg new file mode 100644 index 000000000..470af06b5 --- /dev/null +++ b/src/Assets/IconV2/ic-thermometer.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-ubuntu.svg b/src/Assets/IconV2/ic-ubuntu.svg new file mode 100644 index 000000000..ef0b638ba --- /dev/null +++ b/src/Assets/IconV2/ic-ubuntu.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-user-circle.svg b/src/Assets/IconV2/ic-user-circle.svg new file mode 100644 index 000000000..0870f98db --- /dev/null +++ b/src/Assets/IconV2/ic-user-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/IconV2/ic-wifi-slash.svg b/src/Assets/IconV2/ic-wifi-slash.svg new file mode 100644 index 000000000..a319b6559 --- /dev/null +++ b/src/Assets/IconV2/ic-wifi-slash.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Assets/Img/ic-celebration.svg b/src/Assets/Img/ic-celebration.svg new file mode 100644 index 000000000..5c51f12ca --- /dev/null +++ b/src/Assets/Img/ic-celebration.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Assets/Img/ic-man-on-rocket.svg b/src/Assets/Img/ic-man-on-rocket.svg new file mode 100644 index 000000000..70bbd0991 --- /dev/null +++ b/src/Assets/Img/ic-man-on-rocket.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Common/Checkbox.tsx b/src/Common/Checkbox.tsx deleted file mode 100644 index ee6b18d41..000000000 --- a/src/Common/Checkbox.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { Component } from 'react' -import { CheckboxProps } from './Types' - -/* -Valid States of Checkbox: -1. disabled: true, checked: false, value: XXX -2. disabled: true, checked: true, value: INTERMIDIATE -3. disabled: true, checked: true, value: CHECKED -4. disabled: true, checked: false, value: XXX -5. disabled: false, checked: true, value: INTERMIDIATE -6. disabled: false, checked: true, value: CHECKED -*/ -// TODO: Associate label with input element -export class Checkbox extends Component { - render() { - const rootClassName = `${this.props.rootClassName ? this.props.rootClassName : ''}` - return ( - - ) - } -} diff --git a/src/Common/Checkbox/Checkbox.scss b/src/Common/Checkbox/Checkbox.scss new file mode 100644 index 000000000..54e3a8ad6 --- /dev/null +++ b/src/Common/Checkbox/Checkbox.scss @@ -0,0 +1,99 @@ +.form__checkbox-label { + font-weight: 400; + display: inline-block; + margin-left: 12px; + line-height: 16px; +} + +.form__checkbox__root { + &--gap-8 { + .form__checkbox-label { + margin-left: 8px; + } + } +} + +.form__checkbox-check { + display: none; +} + +$checkbox-hover-bg-image: url('./assets/ic-checkbox-hover.svg'); + +.form__checkbox-container { + width: 20px; + height: 20px; + position: absolute; + left: 0; + background-size: contain; + background-repeat: no-repeat; + background-image: url('./assets/ic-checkbox-unselected.svg'); + transition: background-image 0.17s; + + &:hover { + background-image: $checkbox-hover-bg-image; + } +} + +// Class for checkbox parent container, if added to parent container, hover effect will be applied to checkbox +.checkbox__parent-container { + &:hover { + .form__checkbox-container { + background-image: $checkbox-hover-bg-image; + } + } +} + +.form__checkbox:checked[value='INTERMEDIATE'] ~ .form__checkbox-container { + background-image: url('./assets/ic-checkbox-intermediate.svg'); +} + +.form__checkbox:checked[value='CHECKED'] ~ .form__checkbox-container { + background-image: url('./assets/ic-checkbox-selected.svg'); +} + +.form__checkbox:checked[value='BULK_CHECKED'] ~ .form__checkbox-container { + background-image: url('./assets/ic-bulk-check.svg'); +} + +.form__checkbox:disabled ~ .form__checkbox-label, +.form__checkbox:disabled ~ .form__checkbox-container { + color: var(--N500); + cursor: not-allowed; + opacity: 0.5; +} + +// These are just hack, not to be further extended +.theme { + &__dark { + $checkbox-hover-bg-image: url('./assets/dark/ic-checkbox-hover.svg'); + + .form__checkbox-container { + background-image: url('./assets/dark/ic-checkbox-unselected.svg'); + + &:hover { + background-image: $checkbox-hover-bg-image; + } + } + + // Class for checkbox parent container, if added to parent container, hover effect will be applied to checkbox + .checkbox__parent-container { + &:hover { + .form__checkbox-container { + background-image: $checkbox-hover-bg-image; + } + } + } + + .form__checkbox:checked[value='INTERMEDIATE']~.form__checkbox-container { + background-image: url('./assets/dark/ic-checkbox-intermediate.svg'); + } + + .form__checkbox:checked[value='CHECKED']~.form__checkbox-container { + background-image: url('./assets/dark/ic-checkbox-selected.svg'); + } + + .form__checkbox:checked[value='BULK_CHECKED']~.form__checkbox-container { + background-image: url('./assets/dark/ic-bulk-check.svg'); + } + } +} diff --git a/src/Common/Checkbox/Checkbox.tsx b/src/Common/Checkbox/Checkbox.tsx new file mode 100644 index 000000000..d95747cf4 --- /dev/null +++ b/src/Common/Checkbox/Checkbox.tsx @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CheckboxProps } from '../Types' + +import './Checkbox.scss' + +/* +Valid States of Checkbox: +1. disabled: true, checked: false, value: XXX +2. disabled: true, checked: true, value: INTERMIDIATE +3. disabled: true, checked: true, value: CHECKED +4. disabled: true, checked: false, value: XXX +5. disabled: false, checked: true, value: INTERMIDIATE +6. disabled: false, checked: true, value: CHECKED +*/ +// TODO: Associate label with input element +export const Checkbox = ({ + rootClassName, + onClick, + name, + disabled, + value, + onChange, + tabIndex, + isChecked, + id, + dataTestId, + children, +}: CheckboxProps) => { + const rootClass = `${rootClassName || ''}` + + return ( + // eslint-disable-next-line jsx-a11y/label-has-associated-control + + ) +} diff --git a/src/Common/Checkbox/assets/dark/ic-bulk-check.svg b/src/Common/Checkbox/assets/dark/ic-bulk-check.svg new file mode 100644 index 000000000..e2f95a73a --- /dev/null +++ b/src/Common/Checkbox/assets/dark/ic-bulk-check.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/Assets/Icon/ic-medal.svg b/src/Common/Checkbox/assets/dark/ic-checkbox-hover.svg similarity index 59% rename from src/Assets/Icon/ic-medal.svg rename to src/Common/Checkbox/assets/dark/ic-checkbox-hover.svg index 60e5f8c63..9c4955077 100644 --- a/src/Assets/Icon/ic-medal.svg +++ b/src/Common/Checkbox/assets/dark/ic-checkbox-hover.svg @@ -14,6 +14,7 @@ - limitations under the License. --> - - - \ No newline at end of file + + + + diff --git a/src/Common/Checkbox/assets/dark/ic-checkbox-intermediate.svg b/src/Common/Checkbox/assets/dark/ic-checkbox-intermediate.svg new file mode 100644 index 000000000..936c141c9 --- /dev/null +++ b/src/Common/Checkbox/assets/dark/ic-checkbox-intermediate.svg @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/src/Common/Checkbox/assets/dark/ic-checkbox-selected.svg b/src/Common/Checkbox/assets/dark/ic-checkbox-selected.svg new file mode 100644 index 000000000..ecb5a0019 --- /dev/null +++ b/src/Common/Checkbox/assets/dark/ic-checkbox-selected.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/src/Common/Checkbox/assets/dark/ic-checkbox-unselected.svg b/src/Common/Checkbox/assets/dark/ic-checkbox-unselected.svg new file mode 100644 index 000000000..fefe51fff --- /dev/null +++ b/src/Common/Checkbox/assets/dark/ic-checkbox-unselected.svg @@ -0,0 +1,19 @@ + + + + + diff --git a/src/Common/Checkbox/assets/ic-bulk-check.svg b/src/Common/Checkbox/assets/ic-bulk-check.svg new file mode 100644 index 000000000..b90b19446 --- /dev/null +++ b/src/Common/Checkbox/assets/ic-bulk-check.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/Common/Checkbox/assets/ic-checkbox-hover.svg b/src/Common/Checkbox/assets/ic-checkbox-hover.svg new file mode 100644 index 000000000..2e0d3aaee --- /dev/null +++ b/src/Common/Checkbox/assets/ic-checkbox-hover.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/src/Common/Checkbox/assets/ic-checkbox-intermediate.svg b/src/Common/Checkbox/assets/ic-checkbox-intermediate.svg new file mode 100644 index 000000000..bec37de4b --- /dev/null +++ b/src/Common/Checkbox/assets/ic-checkbox-intermediate.svg @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/src/Common/Checkbox/assets/ic-checkbox-selected.svg b/src/Common/Checkbox/assets/ic-checkbox-selected.svg new file mode 100644 index 000000000..b5d0eb365 --- /dev/null +++ b/src/Common/Checkbox/assets/ic-checkbox-selected.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/src/Common/Checkbox/assets/ic-checkbox-unselected.svg b/src/Common/Checkbox/assets/ic-checkbox-unselected.svg new file mode 100644 index 000000000..a64391cf6 --- /dev/null +++ b/src/Common/Checkbox/assets/ic-checkbox-unselected.svg @@ -0,0 +1,19 @@ + + + + + diff --git a/src/Common/Checkbox/index.ts b/src/Common/Checkbox/index.ts new file mode 100644 index 000000000..0dab11563 --- /dev/null +++ b/src/Common/Checkbox/index.ts @@ -0,0 +1 @@ +export * from './Checkbox' diff --git a/src/Common/Common.service.ts b/src/Common/Common.service.ts index c7d1a3f13..c99e0a6ff 100644 --- a/src/Common/Common.service.ts +++ b/src/Common/Common.service.ts @@ -45,6 +45,7 @@ import { GlobalVariableDTO, GlobalVariableOptionType, UserRole, + APIOptions, EnvAppsMetaDTO, GetAppsInfoForEnvProps, AppMeta, @@ -452,9 +453,9 @@ export function getClusterListMin() { export const getResourceGroupListRaw = (clusterId: string): Promise> => get(`${ROUTES.API_RESOURCE}/${ROUTES.GVK}/${clusterId}`) -export function getNamespaceListMin(clusterIdsCsv: string): Promise { +export function getNamespaceListMin(clusterIdsCsv: string, abortControllerRef?: APIOptions['abortControllerRef']): Promise { const URL = `${ROUTES.NAMESPACE}/autocomplete?ids=${clusterIdsCsv}` - return get(URL) + return get(URL, { abortControllerRef }) } export function getWebhookEventsForEventId(eventId: string | number) { const URL = `${ROUTES.GIT_HOST_EVENT}/${eventId}` diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index ad1b89398..49ce89f06 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -30,6 +30,7 @@ export const DOCUMENTATION = { GLOBAL_CONFIG_BUILD_INFRA: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/global-configurations/build-infra`, ENTERPRISE_LICENSE: `${DOCUMENTATION_HOME_PAGE}/enterprise-license`, KUBE_CONFIG: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/resource-browser#running-kubectl-commands-locally`, + TENANT_INSTALLATION: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/software-distribution-hub/tenants`, } export const PATTERNS = { @@ -64,7 +65,6 @@ export const URLS = { CREATE_JOB: 'create-job', GETTING_STARTED: 'getting-started', STACK_MANAGER_ABOUT: '/stack-manager/about', - APP_LIST_HELM: 'h', APP_CI_DETAILS: 'ci-details', LOGS: 'Logs', CREATE: '/create', @@ -86,7 +86,6 @@ export const URLS = { COMPARE_CLUSTERS: '/compare-clusters', APP_CONFIG: 'edit', GLOBAL_CONFIG: '/global-config', - CONFIG_DRIFT: 'config-drift', GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP, GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP_CREATE: `${GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP}/create`, // NOTE: using appId since we are re-using AppConfig component @@ -135,6 +134,7 @@ export const ROUTES = { ATTRIBUTES_CREATE: 'attributes/create', ATTRIBUTES_UPDATE: 'attributes/update', APP_LIST_MIN: 'app/min', + APP_DETAIL: 'app/detail', CLUSTER_LIST_MIN: 'cluster/autocomplete', CLUSTER_LIST_RAW: 'k8s/capacity/cluster/list/raw', PLUGIN_GLOBAL_LIST_DETAIL_V2: 'plugin/global/list/detail/v2', diff --git a/src/Common/Drawer/Drawer.tsx b/src/Common/Drawer/Drawer.tsx index 57fefae9c..d33d57acb 100644 --- a/src/Common/Drawer/Drawer.tsx +++ b/src/Common/Drawer/Drawer.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { useRef, useEffect } from 'react' +import { useRef, useEffect } from 'react' import { preventBodyScroll } from '../../Shared' import { VisibleModal } from '../Modals/VisibleModal' import './Drawer.scss' diff --git a/src/Common/Drawer/index.ts b/src/Common/Drawer/index.ts new file mode 100644 index 000000000..04766cfab --- /dev/null +++ b/src/Common/Drawer/index.ts @@ -0,0 +1 @@ +export * from './Drawer' diff --git a/src/Common/EmptyState/index.ts b/src/Common/EmptyState/index.ts new file mode 100644 index 000000000..69d94377b --- /dev/null +++ b/src/Common/EmptyState/index.ts @@ -0,0 +1,2 @@ +export { default as GenericEmptyState } from './GenericEmptyState' +export { default as GenericFilterEmptyState } from './GenericFilterEmptyState' diff --git a/src/Common/Helper.tsx b/src/Common/Helper.tsx index 76cd26c9d..d060a1042 100644 --- a/src/Common/Helper.tsx +++ b/src/Common/Helper.tsx @@ -17,7 +17,7 @@ import React, { SyntheticEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react' import DOMPurify from 'dompurify' import { JSONPath, JSONPathOptions } from 'jsonpath-plus' -import { compare as compareJSON, applyPatch, unescapePathComponent,deepClone } from 'fast-json-patch' +import { compare as compareJSON, applyPatch, unescapePathComponent, deepClone } from 'fast-json-patch' import { components } from 'react-select' import * as Sentry from '@sentry/browser' import moment from 'moment' @@ -43,6 +43,7 @@ import { ToastVariantType, versionComparatorBySortOrder, WebhookEventNameType, + AppType, } from '../Shared' import { ReactComponent as ArrowDown } from '@Icons/ic-chevron-down.svg' import { ReactComponent as ICWebhook } from '@Icons/ic-webhook.svg' @@ -516,7 +517,7 @@ export const getUrlWithSearchParams = ({ @@ -614,7 +615,10 @@ const buildObjectFromPathTokens = (index: number, tokens: string[], value: any) const numberKey = Number(key) const isKeyNumber = !Number.isNaN(numberKey) return isKeyNumber - ? [...Array(numberKey).fill(UNCHANGED_ARRAY_ELEMENT_SYMBOL), buildObjectFromPathTokens(index + 1, tokens, value)] + ? [ + ...Array(numberKey).fill(UNCHANGED_ARRAY_ELEMENT_SYMBOL), + buildObjectFromPathTokens(index + 1, tokens, value), + ] : { [unescapePathComponent(key)]: buildObjectFromPathTokens(index + 1, tokens, value) } } @@ -664,7 +668,12 @@ export const powerSetOfSubstringsFromStart = (strings: string[], regex: RegExp) }) export const convertJSONPointerToJSONPath = (pointer: string) => - unescapePathComponent(pointer.replace(/\/([\*0-9]+)\//g, '[$1].').replace(/\//g, '.').replace(/\./, '$.')) + unescapePathComponent( + pointer + .replace(/\/([\*0-9]+)\//g, '[$1].') + .replace(/\//g, '.') + .replace(/\./, '$.'), + ) export const flatMapOfJSONPaths = ( paths: string[], @@ -679,6 +688,7 @@ export const applyCompareDiffOnUneditedDocument = (uneditedDocument: object, edi /** * Returns a debounced variant of the function + * @deprecated - It should use useRef instead, pls use useDebounce */ export const debounce = (func, timeout = 500) => { let timer @@ -693,6 +703,17 @@ export const debounce = (func, timeout = 500) => { } } +export const useDebounce = void>(cb: Callback, delay: number) => { + const timeoutId = useRef>(null) + + return (...args: Parameters) => { + if (timeoutId.current) { + clearTimeout(timeoutId.current) + } + timeoutId.current = setTimeout(() => cb(...args), delay) + } +} + /** * Returns a capitalized string with first letter in uppercase and rest in lowercase */ @@ -989,7 +1010,7 @@ export const getBranchIcon = (sourceType, _isRegex?: boolean, webhookEventName?: return } if (webhookEventName === WebhookEventNameType.TAG_CREATION) { - return + return } return } @@ -1013,7 +1034,6 @@ export const getIframeWithDefaultAttributes = (iframeString: string, defaultName const parentDiv = document.createElement('div') parentDiv.innerHTML = getSanitizedIframe(iframeString) - const iframe = parentDiv.querySelector('iframe') if (iframe) { if (!iframe.hasAttribute('title') && !!defaultName) { @@ -1082,5 +1102,34 @@ export const getTTLInHumanReadableFormat = (ttl: number): string => { } const humanizedDuration = moment.duration(absoluteTTL, 'seconds').humanize(false) // Since moment.js return "a" or "an" for singular values so replacing with 1. - return humanizedDuration.replace(/^(a|an) /, '1 '); -} \ No newline at end of file + return humanizedDuration.replace(/^(a|an) /, '1 ') +} + +const getAppTypeCategory = (appType: AppType) => { + switch (appType) { + case AppType.DEVTRON_APP: + return 'DA' + case AppType.DEVTRON_HELM_CHART: + case AppType.EXTERNAL_HELM_CHART: + return 'HA' + case AppType.EXTERNAL_ARGO_APP: + return 'ACD' + case AppType.EXTERNAL_FLUX_APP: + return 'FCD' + default: + return 'DA' + } +} + +export const getAIAnalyticsEvents = (context: string, appType?: AppType) => + `AI_${appType ? `${getAppTypeCategory(appType)}_` : ''}${context}` + +export const findRight = (arr: T[], predicate: (item: T) => boolean): T | null => { + for (let i = arr.length - 1; i >= 0; i--) { + if (predicate(arr[i])) { + return arr[i] + } + } + + return null +} diff --git a/src/Common/RJSF/templates/ObjectFieldTemplate.tsx b/src/Common/RJSF/templates/ObjectFieldTemplate.tsx index 825b18293..fffbd4bc5 100644 --- a/src/Common/RJSF/templates/ObjectFieldTemplate.tsx +++ b/src/Common/RJSF/templates/ObjectFieldTemplate.tsx @@ -76,8 +76,6 @@ const Field = ({ return true } }) - // NOTE: we probably should use uiSchema instead? - .sort((prop) => (schema.properties?.[prop.name]?.type === 'boolean' ? -1 : 1)) .map((prop) => prop.content) if (hasAdditionalProperties) { diff --git a/src/Common/SegmentedBarChart/SegmentedBarChart.tsx b/src/Common/SegmentedBarChart/SegmentedBarChart.tsx index 33d64f26d..cf842a68c 100644 --- a/src/Common/SegmentedBarChart/SegmentedBarChart.tsx +++ b/src/Common/SegmentedBarChart/SegmentedBarChart.tsx @@ -23,6 +23,7 @@ import { Entity, SegmentedBarChartProps } from './types' import './styles.scss' const SegmentedBarChart: React.FC = ({ + hideLegend, entities: userEntities = [FALLBACK_ENTITY], rootClassName, countClassName, @@ -36,7 +37,7 @@ const SegmentedBarChart: React.FC = ({ const total = entities.reduce((sum, entity) => entity.value + sum, 0) const filteredEntities = entities.filter((entity) => !!entity.value) - const calcSegmentWidth = (entity: Entity) => `${(entity.value / total) * 100}%` + const calcSegmentWidth = (entityValue: Entity['value']) => `${(entityValue / total) * 100}%` const renderLabel = (label: Entity['label']) => isLoading ? ( @@ -88,11 +89,17 @@ const SegmentedBarChart: React.FC = ({ )) } - const renderLegend = () => ( -
- {renderContent()} -
- ) + const renderLegend = () => { + if (hideLegend) { + return null + } + + return ( +
+ {renderContent()} +
+ ) + } const renderBar = () => ( = ({ className={`h-8 ${index === 0 ? 'dc__left-radius-4' : ''} ${ index === map.length - 1 ? 'dc__right-radius-4' : '' } ${isLoading ? 'shimmer' : ''}`} - style={{ backgroundColor: entity.color, width: calcSegmentWidth(entity) }} + style={{ backgroundColor: entity.color, width: calcSegmentWidth(entity.value) }} /> ))} diff --git a/src/Common/SegmentedBarChart/types.ts b/src/Common/SegmentedBarChart/types.ts index ea56fc846..b0153715f 100644 --- a/src/Common/SegmentedBarChart/types.ts +++ b/src/Common/SegmentedBarChart/types.ts @@ -20,8 +20,17 @@ export type Entity = { value: number } -export interface SegmentedBarChartProps { - entities: NonNullable +type EntityPropType = + | { + hideLegend?: false + entities: NonNullable + } + | { + hideLegend: true + entities: NonNullable & { label?: never }>[] + } + +export type SegmentedBarChartProps = { rootClassName?: string countClassName?: string labelClassName?: string @@ -29,4 +38,4 @@ export interface SegmentedBarChartProps { swapLegendAndBar?: boolean showAnimationOnBar?: boolean isLoading?: boolean -} +} & EntityPropType diff --git a/src/Common/SegmentedControl/Segment.tsx b/src/Common/SegmentedControl/Segment.tsx index 19f28853b..437fc9020 100644 --- a/src/Common/SegmentedControl/Segment.tsx +++ b/src/Common/SegmentedControl/Segment.tsx @@ -1,8 +1,9 @@ -import { ReactElement } from 'react' +import { ReactElement, useMemo } from 'react' import { Tooltip } from '@Common/Tooltip' import { Icon } from '@Shared/Components' import { ComponentSizeType } from '@Shared/constants' +import { getUniqueId } from '@Shared/Helpers' import { ConditionalWrap } from '../Helper' import { COMPONENT_SIZE_TO_ICON_CLASS_MAP, COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP } from './constants' @@ -24,6 +25,8 @@ const Segment = ({ size, disabled, }: SegmentProps) => { + const inputId = useMemo(getUniqueId, []) + const { value, icon, isError, label, tooltipProps, ariaLabel } = segment const handleChange = () => { onChange(segment) @@ -32,13 +35,13 @@ const Segment = ({ return (