mirror of
https://github.com/harness/drone.git
synced 2025-05-04 09:21:08 +08:00
Sync UI template with latest updates
This commit is contained in:
parent
66fea2a730
commit
7c6da77a27
@ -35,6 +35,12 @@ settings:
|
||||
typescript:
|
||||
alwaysTryTypes: true
|
||||
rules:
|
||||
'@typescript-eslint/ban-types':
|
||||
- error
|
||||
- extendDefaults: true
|
||||
types:
|
||||
'{}': false
|
||||
|
||||
# custom rules
|
||||
no-document-body-snapshot: 2
|
||||
duplicate-data-tooltip-id: 'warn'
|
||||
|
@ -1,48 +1,44 @@
|
||||
const packageJSON = require('../package.json');
|
||||
const { pick, omit, mapValues } = require('lodash');
|
||||
const packageJSON = require('../package.json')
|
||||
const { pick, omit, mapValues } = require('lodash')
|
||||
|
||||
/**
|
||||
* These packages must be stricly shared with exact versions
|
||||
*/
|
||||
const ExactSharedPackages = [
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-router-dom',
|
||||
'@harness/use-modal',
|
||||
'@blueprintjs/core',
|
||||
'@blueprintjs/select',
|
||||
'@blueprintjs/datetime',
|
||||
'restful-react',
|
||||
'@harness/monaco-yaml',
|
||||
'monaco-editor',
|
||||
'monaco-editor-core',
|
||||
'monaco-languages',
|
||||
'monaco-plugin-helpers',
|
||||
'react-monaco-editor'
|
||||
]
|
||||
const ExactSharedPackages = [
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-router-dom',
|
||||
'@harness/use-modal',
|
||||
'@blueprintjs/core',
|
||||
'@blueprintjs/select',
|
||||
'@blueprintjs/datetime',
|
||||
'restful-react',
|
||||
'@harness/monaco-yaml',
|
||||
'monaco-editor',
|
||||
'monaco-editor-core',
|
||||
'monaco-languages',
|
||||
'monaco-plugin-helpers',
|
||||
'react-monaco-editor'
|
||||
]
|
||||
|
||||
/**
|
||||
* @type {import('webpack').ModuleFederationPluginOptions}
|
||||
*/
|
||||
module.exports = {
|
||||
name: 'governance',
|
||||
filename: 'remoteEntry.js',
|
||||
library: {
|
||||
type: 'var',
|
||||
name: 'governance'
|
||||
},
|
||||
exposes: {
|
||||
'./App': './src/App.tsx',
|
||||
'./EvaluationModal': './src/modals/EvaluationModal/EvaluationModal.tsx',
|
||||
'./PipelineGovernanceView': './src/views/PipelineGovernanceView/PipelineGovernanceView.tsx',
|
||||
'./EvaluationView': './src/views/EvaluationView/EvaluationView.tsx',
|
||||
'./PolicySetWizard': './src/pages/PolicySets/components/PolicySetWizard.tsx'
|
||||
},
|
||||
shared: {
|
||||
formik: packageJSON.dependencies['formik'],
|
||||
...mapValues(pick(packageJSON.dependencies, ExactSharedPackages), version => ({
|
||||
singleton: true,
|
||||
requiredVersion: version
|
||||
}))
|
||||
}
|
||||
};
|
||||
name: 'governance',
|
||||
filename: 'remoteEntry.js',
|
||||
library: {
|
||||
type: 'var',
|
||||
name: 'governance'
|
||||
},
|
||||
exposes: {
|
||||
'./App': './src/App.tsx'
|
||||
},
|
||||
shared: {
|
||||
formik: packageJSON.dependencies['formik'],
|
||||
...mapValues(pick(packageJSON.dependencies, ExactSharedPackages), version => ({
|
||||
singleton: true,
|
||||
requiredVersion: version
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
describe('dashboard', () => {
|
||||
it('load the dashboard', () => {
|
||||
cy.visit('/')
|
||||
cy.contains('In Effect')
|
||||
cy.contains('Policy Evaluations')
|
||||
cy.contains('Failures Recorded')
|
||||
})
|
||||
it('load the dashboard', () => {
|
||||
// cy.visit('/')
|
||||
// cy.contains('In Effect')
|
||||
// cy.contains('Policy Evaluations')
|
||||
// cy.contains('Failures Recorded')
|
||||
})
|
||||
})
|
||||
|
@ -1,9 +0,0 @@
|
||||
// disabling at the moment because of logic around Evaluations tab being removed in standalone mode (account in NG equivalent)
|
||||
|
||||
// describe('evaluations', () => {
|
||||
// it('load the table', () => {
|
||||
// cy.visit('/')
|
||||
// cy.contains('Evaluations').click()
|
||||
// cy.contains('Policy evaluations are created when policy sets are enforced on your Harness entities.')
|
||||
// })
|
||||
// })
|
@ -1,7 +0,0 @@
|
||||
describe('policies', () => {
|
||||
it('load the table', () => {
|
||||
cy.visit('/')
|
||||
cy.contains('Policies').click()
|
||||
cy.get('[class="TableV2--row TableV2--card TableV2--clickable"]').should('have.length', 12)
|
||||
})
|
||||
})
|
@ -1,7 +0,0 @@
|
||||
describe('policy sets', () => {
|
||||
it('load the table', () => {
|
||||
cy.visit('/')
|
||||
cy.contains('Policy Set').click()
|
||||
cy.contains('A harness policy set allows you to group policies and configure where they will be enforced.')
|
||||
})
|
||||
})
|
@ -141,8 +141,8 @@
|
||||
"@types/testing-library__user-event": "^4.1.1",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@types/yup": "^0.29.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.1",
|
||||
"@typescript-eslint/parser": "^5.33.1",
|
||||
"@urql/devtools": "^2.0.3",
|
||||
"@zerollup/ts-transform-paths": "^1.7.18",
|
||||
"assert": "^2.0.0",
|
||||
@ -199,7 +199,7 @@
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node": "^10.2.1",
|
||||
"tsconfig-paths-webpack-plugin": "^3.5.1",
|
||||
"typescript": "^4.2.4",
|
||||
"typescript": "^4.7.4",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.58.0",
|
||||
"webpack-bugsnag-plugins": "^1.8.0",
|
||||
|
@ -13,7 +13,10 @@ const AppContext = React.createContext<AppContextProps>({
|
||||
components: {}
|
||||
})
|
||||
|
||||
export const AppContextProvider: React.FC<{ value: AppProps }> = React.memo(({ value: initialValue, children }) => {
|
||||
export const AppContextProvider: React.FC<{ value: AppProps }> = React.memo(function AppContextProvider({
|
||||
value: initialValue,
|
||||
children
|
||||
}) {
|
||||
const [appStates, setAppStates] = useState<AppProps>(initialValue)
|
||||
|
||||
return (
|
||||
|
@ -1,7 +1,6 @@
|
||||
import type React from 'react'
|
||||
import type * as History from 'history'
|
||||
import type { PermissionOptionsMenuButtonProps } from 'components/Permissions/PermissionsOptionsMenuButton'
|
||||
import type { OverviewChartsWithToggleProps } from 'components/OverviewChartsWithToggle/OverviewChartsWithToggle'
|
||||
import type { LangLocale } from './framework/strings/languageLoader'
|
||||
import type { FeatureFlagMap, GitFiltersProps } from './utils/GovernanceUtils'
|
||||
|
||||
@ -106,5 +105,4 @@ export interface AppPropsComponent {
|
||||
navigate: (path: string) => void
|
||||
shouldBlockNavigation?: (location: History.Location) => boolean
|
||||
}>
|
||||
OverviewChartsWithToggle: React.FC<OverviewChartsWithToggleProps>
|
||||
}
|
||||
|
@ -3,12 +3,14 @@ import type { AppPathProps } from 'AppProps'
|
||||
|
||||
export enum RoutePath {
|
||||
SIGNIN = '/signin',
|
||||
SIGNUP = '/signup',
|
||||
REGISTER = '/register',
|
||||
POLICY_DASHBOARD = '/dashboard',
|
||||
POLICY_LISTING = '/policies',
|
||||
POLICY_NEW = '/policies/new',
|
||||
POLICY_VIEW = '/policies/view/:policyIdentifier',
|
||||
//POLICY_EDIT = '/policies/edit/:policyIdentifier',
|
||||
POLICY_EDIT= '/policies/edit/:policyIdentifier/:repo?/:branch?',
|
||||
POLICY_EDIT = '/policies/edit/:policyIdentifier/:repo?/:branch?',
|
||||
POLICY_SETS_LISTING = '/policy-sets',
|
||||
POLICY_SETS_DETAIL = '/policy-sets/:policySetIdentifier',
|
||||
POLICY_EVALUATIONS_LISTING = '/policy-evaluations',
|
||||
@ -17,10 +19,12 @@ export enum RoutePath {
|
||||
|
||||
export default {
|
||||
toSignIn: (): string => toRouteURL(RoutePath.SIGNIN),
|
||||
toSignUp: (): string => toRouteURL(RoutePath.SIGNUP),
|
||||
toRegister: (): string => toRouteURL(RoutePath.REGISTER),
|
||||
toPolicyDashboard: (): string => toRouteURL(RoutePath.POLICY_DASHBOARD),
|
||||
toPolicyListing: (): string => toRouteURL(RoutePath.POLICY_LISTING),
|
||||
toPolicyNew: (): string => toRouteURL(RoutePath.POLICY_NEW),
|
||||
toPolicyView: ({ policyIdentifier }: Required<Pick<AppPathProps, 'policyIdentifier'>>): string =>
|
||||
toPolicyView: ({ policyIdentifier }: Required<Pick<AppPathProps, 'policyIdentifier'>>): string =>
|
||||
toRouteURL(RoutePath.POLICY_VIEW, { policyIdentifier }),
|
||||
toPolicyEdit: ({ policyIdentifier }: Required<Pick<AppPathProps, 'policyIdentifier'>>): string =>
|
||||
toRouteURL(RoutePath.POLICY_EDIT, { policyIdentifier }),
|
||||
|
@ -1,105 +1,76 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React, { useCallback } from 'react'
|
||||
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom'
|
||||
import { SignInPage } from 'pages/signin/SignInPage'
|
||||
// import { SignInPage } from 'pages/signin/SignInPage'
|
||||
import { NotFoundPage } from 'pages/404/NotFoundPage'
|
||||
import { SignIn } from 'pages/SignIn/SignIn'
|
||||
import { Register } from 'pages/Register/Register'
|
||||
import { routePath, standaloneRoutePath } from './RouteUtils'
|
||||
import { RoutePath } from './RouteDefinitions'
|
||||
import PolicyControlPage from './pages/PolicyControl/PolicyControlPage'
|
||||
import Policies from './pages/Policies/Policies'
|
||||
import PolicyDashboard from './pages/PolicyDashboard/PolicyDashboard'
|
||||
import PolicySets from './pages/PolicySets/PolicySets'
|
||||
import PolicyEvaluations from './pages/PolicyEvaluations/PolicyEvaluations'
|
||||
import { EditPolicy } from './pages/EditPolicy/EditPolicy'
|
||||
import { ViewPolicy } from './pages/ViewPolicy/ViewPolicy'
|
||||
import { PolicySetDetail } from './pages/PolicySetDetail/PolicySetDetail'
|
||||
import { EvaluationDetail } from './pages/EvaluationDetail/EvaluationDetail'
|
||||
|
||||
export const RouteDestinations: React.FC<{ standalone: boolean }> = React.memo(
|
||||
({ standalone }) => {
|
||||
// TODO: Add Auth wrapper
|
||||
|
||||
const Destinations: React.FC = useCallback(
|
||||
() => (
|
||||
<Switch>
|
||||
{standalone && (
|
||||
export const RouteDestinations: React.FC<{ standalone: boolean }> = React.memo(({ standalone }) => {
|
||||
const Destinations: React.FC = useCallback(
|
||||
() => (
|
||||
<Switch>
|
||||
{standalone && (
|
||||
<>
|
||||
<Route path={routePath(RoutePath.SIGNIN)}>
|
||||
<SignInPage />
|
||||
<SignIn />
|
||||
</Route>
|
||||
)}
|
||||
<Route path={routePath(RoutePath.SIGNUP)}>
|
||||
<SignIn />
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.REGISTER)}>
|
||||
<Register />
|
||||
</Route>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_DASHBOARD)}>
|
||||
<PolicyControlPage titleKey="overview">
|
||||
<PolicyDashboard />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_DASHBOARD)}>
|
||||
<h1>Overview</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_NEW)}>
|
||||
<PolicyControlPage titleKey="common.policy.newPolicy">
|
||||
<EditPolicy />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_NEW)}>
|
||||
<h1>New</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_VIEW)}>
|
||||
<PolicyControlPage titleKey="governance.viewPolicy">
|
||||
<ViewPolicy />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_VIEW)}>
|
||||
<h1>View</h1>
|
||||
</Route>
|
||||
|
||||
<Route exact path={routePath(RoutePath.POLICY_EDIT)}>
|
||||
<PolicyControlPage titleKey="governance.editPolicy">
|
||||
<EditPolicy />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route exact path={routePath(RoutePath.POLICY_EDIT)}>
|
||||
<h1>Edit</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_LISTING)}>
|
||||
<PolicyControlPage titleKey="common.policies">
|
||||
<Policies />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_LISTING)}>
|
||||
<h1>Listing</h1>
|
||||
</Route>
|
||||
|
||||
<Route exact path={routePath(RoutePath.POLICY_SETS_LISTING)}>
|
||||
<PolicyControlPage titleKey="common.policy.policysets">
|
||||
<PolicySets />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route exact path={routePath(RoutePath.POLICY_SETS_LISTING)}>
|
||||
<h1>Listing 2</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_SETS_DETAIL)}>
|
||||
<PolicyControlPage titleKey="common.policy.policysets">
|
||||
<PolicySetDetail />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_SETS_DETAIL)}>
|
||||
<h1>Detail 1</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_EVALUATION_DETAIL)}>
|
||||
<PolicyControlPage titleKey="governance.evaluations">
|
||||
<EvaluationDetail />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path={routePath(RoutePath.POLICY_EVALUATION_DETAIL)}>
|
||||
<h1>Detail 2</h1>
|
||||
</Route>
|
||||
|
||||
<Route path={routePath(RoutePath.POLICY_EVALUATIONS_LISTING)}>
|
||||
<PolicyControlPage titleKey="governance.evaluations">
|
||||
<PolicyEvaluations />
|
||||
</PolicyControlPage>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
{standalone ? <Redirect to={standaloneRoutePath(RoutePath.POLICY_DASHBOARD)} /> : <NotFoundPage />}
|
||||
</Route>
|
||||
</Switch>
|
||||
),
|
||||
[standalone]
|
||||
)
|
||||
|
||||
<Route path="/">
|
||||
{standalone ? (
|
||||
<Redirect to={standaloneRoutePath(RoutePath.POLICY_DASHBOARD)} />
|
||||
) : (
|
||||
<NotFoundPage />
|
||||
)}
|
||||
</Route>
|
||||
</Switch>
|
||||
),
|
||||
[standalone]
|
||||
)
|
||||
|
||||
return standalone ? (
|
||||
<HashRouter>
|
||||
<Destinations />
|
||||
</HashRouter>
|
||||
) : (
|
||||
return standalone ? (
|
||||
<HashRouter>
|
||||
<Destinations />
|
||||
)
|
||||
}
|
||||
)
|
||||
</HashRouter>
|
||||
) : (
|
||||
<Destinations />
|
||||
)
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import './App.scss'
|
||||
// This flag is used in services/config.ts to customize API path when app is run
|
||||
// in multiple modes (standalone vs. embedded).
|
||||
// Also being used in when generating proper URLs inside the app.
|
||||
window.STRIP_PM_PREFIX = true
|
||||
window.STRIP_SCM_PREFIX = true
|
||||
|
||||
ReactDOM.render(
|
||||
<App
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Classes, Menu } from '@blueprintjs/core'
|
||||
import { Classes, IMenuItemProps, Menu } from '@blueprintjs/core'
|
||||
import { Button, ButtonProps } from '@harness/uicore'
|
||||
import type { PopoverProps } from '@harness/uicore/dist/components/Popover/Popover'
|
||||
|
||||
@ -23,7 +23,7 @@ export const OptionsMenuButton = ({ items, ...props }: OptionsMenuButtonProps):
|
||||
<Menu.Item
|
||||
key={(item as React.ComponentProps<typeof Menu.Item>)?.text as string}
|
||||
className={Classes.POPOVER_DISMISS}
|
||||
{...item}
|
||||
{...(item as IMenuItemProps & React.AnchorHTMLAttributes<HTMLAnchorElement>)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
import mustache from 'mustache'
|
||||
import { get } from 'lodash-es'
|
||||
|
||||
import { useStringsContext, StringKeys } from './StringsContext'
|
||||
|
||||
export interface UseStringsReturn {
|
||||
@ -46,9 +45,9 @@ export function String(props: StringProps): React.ReactElement | null {
|
||||
const text = getString(stringID, vars)
|
||||
|
||||
return useRichText ? (
|
||||
<Tag {...(rest as unknown)} dangerouslySetInnerHTML={{ __html: text }} />
|
||||
<Tag {...(rest as unknown as {})} dangerouslySetInnerHTML={{ __html: text }} />
|
||||
) : (
|
||||
<Tag {...(rest as unknown)}>{text}</Tag>
|
||||
<Tag {...(rest as unknown as {})}>{text}</Tag>
|
||||
)
|
||||
} catch (e) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
|
@ -56,10 +56,12 @@ export interface StringsMap {
|
||||
descriptionPlaceholder: string
|
||||
details: string
|
||||
edit: string
|
||||
email: string
|
||||
entity: string
|
||||
'evaluation.evaluatedPoliciesCount': string
|
||||
'evaluation.onePolicyEvaluated': string
|
||||
executionsText: string
|
||||
existingAccount: string
|
||||
failed: string
|
||||
fileOverwrite: string
|
||||
finish: string
|
||||
@ -122,13 +124,18 @@ export interface StringsMap {
|
||||
navigationCheckText: string
|
||||
navigationCheckTitle: string
|
||||
no: string
|
||||
noAccount: string
|
||||
noSearchResultsFound: string
|
||||
optionalField: string
|
||||
outputLabel: string
|
||||
overview: string
|
||||
pageNotFound: string
|
||||
password: string
|
||||
samplePolicies: string
|
||||
saveOverwrite: string
|
||||
search: string
|
||||
signIn: string
|
||||
signUp: string
|
||||
source: string
|
||||
status: string
|
||||
success: string
|
||||
|
2
web/src/global.d.ts
vendored
2
web/src/global.d.ts
vendored
@ -45,7 +45,7 @@ declare module '*.gql' {
|
||||
declare interface Window {
|
||||
apiUrl: string
|
||||
bugsnagClient?: any
|
||||
STRIP_PM_PREFIX?: boolean
|
||||
STRIP_SCM_PREFIX?: boolean
|
||||
}
|
||||
|
||||
declare const monaco: any
|
||||
|
@ -1,3 +1,10 @@
|
||||
pageNotFound: Page Not Found
|
||||
signIn: Sign In
|
||||
signUp: Sign Up
|
||||
email: Email
|
||||
password: Password
|
||||
noAccount: No Account
|
||||
existingAccount: Existing Account
|
||||
failed: Failed
|
||||
status: Status
|
||||
success: Success
|
||||
|
15
web/src/pages/Account/Account.module.scss.d.ts
vendored
15
web/src/pages/Account/Account.module.scss.d.ts
vendored
@ -1,15 +0,0 @@
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Copyright 2021 Harness Inc. All rights reserved.
|
||||
* Use of this source code is governed by the PolyForm Shield 1.0.0 license
|
||||
* that can be found in the licenses directory at the root of this repository, also available at
|
||||
* https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
|
||||
**/
|
||||
// this is an auto-generated file, do not update this manually
|
||||
declare const styles: {
|
||||
readonly container: string
|
||||
readonly input: string
|
||||
readonly minWidth: string
|
||||
readonly root: string
|
||||
}
|
||||
export default styles
|
@ -1,153 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import {
|
||||
Container,
|
||||
Button,
|
||||
Formik,
|
||||
FormikForm,
|
||||
FormInput,
|
||||
Text,
|
||||
Color,
|
||||
Layout,
|
||||
ButtonVariation,
|
||||
Page,
|
||||
useToaster
|
||||
} from '@harness/uicore'
|
||||
import { useUpdateUser, useGetUser } from 'services/pm'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import routes from 'RouteDefinitions'
|
||||
|
||||
import styles from './Account.module.scss'
|
||||
|
||||
interface UserFormProps {
|
||||
name: string
|
||||
email: string
|
||||
password1: string
|
||||
password2: string
|
||||
}
|
||||
|
||||
export const Account = () => {
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { showSuccess, showError } = useToaster()
|
||||
const { data, loading, error, refetch } = useGetUser({})
|
||||
const { mutate } = useUpdateUser({})
|
||||
const [editDetails, setEditDetails] = useState(false)
|
||||
const [name, setName] = useState<string | undefined>('')
|
||||
const [email, setEmail] = useState<string | undefined>('')
|
||||
|
||||
useEffect(() => {
|
||||
setName(data?.name)
|
||||
setEmail(data?.email)
|
||||
}, [data])
|
||||
|
||||
if (error) {
|
||||
history.push(routes.toLogin())
|
||||
}
|
||||
|
||||
const updateUserDetails = async ({ email, name, password1 }: UserFormProps) => {
|
||||
try {
|
||||
await mutate({ email, name, password: password1 })
|
||||
showSuccess(getString('common.itemUpdated'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error({ err })
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = (data: UserFormProps): void => {
|
||||
setEditDetails(false)
|
||||
updateUserDetails(data)
|
||||
}
|
||||
|
||||
const editUserForm = (
|
||||
<Formik<UserFormProps>
|
||||
initialValues={{ name: name as string, email: email as string, password1: '', password2: '' }}
|
||||
formName="newPipelineForm"
|
||||
onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'flex-start' }} margin={{ bottom: 'large' }}>
|
||||
<Text color={Color.GREY_600} className={styles.minWidth}>
|
||||
{getString('common.name')}
|
||||
</Text>
|
||||
<FormInput.Text name="name" className={styles.input} />
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'flex-start' }} margin={{ bottom: 'large' }}>
|
||||
<Text color={Color.GREY_600} className={styles.minWidth}>
|
||||
{getString('common.email')}
|
||||
</Text>
|
||||
<FormInput.Text name="email" className={styles.input} />
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'flex-start' }} margin={{ bottom: 'large' }}>
|
||||
<Text color={Color.GREY_600} className={styles.minWidth}>
|
||||
{getString('password')}
|
||||
</Text>
|
||||
<FormInput.Text
|
||||
name="password1"
|
||||
label="Password"
|
||||
inputGroup={{ type: 'password' }}
|
||||
className={styles.input}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="password2"
|
||||
label="Re-type your Password"
|
||||
inputGroup={{ type: 'password' }}
|
||||
className={styles.input}
|
||||
/>
|
||||
</Layout.Horizontal>
|
||||
<Button variation={ButtonVariation.LINK} icon="updated" text={getString('common.save')} type="submit" />
|
||||
</FormikForm>
|
||||
</Formik>
|
||||
)
|
||||
|
||||
return (
|
||||
<Container className={styles.root} height="inherit">
|
||||
<Page.Header title={getString('common.accountOverview')} />
|
||||
<Page.Body
|
||||
loading={loading}
|
||||
retryOnError={() => refetch()}
|
||||
error={(error?.data as Error)?.message || error?.message}>
|
||||
<Container margin="xlarge" padding="xlarge" className={styles.container} background="white">
|
||||
<Text color={Color.BLACK} font={{ weight: 'semi-bold', size: 'medium' }} margin={{ bottom: 'xlarge' }}>
|
||||
{getString('common.accountDetails')}
|
||||
</Text>
|
||||
{editDetails ? (
|
||||
editUserForm
|
||||
) : (
|
||||
<>
|
||||
<Layout.Horizontal
|
||||
flex={{ alignItems: 'center', justifyContent: 'flex-start' }}
|
||||
margin={{ bottom: 'large' }}>
|
||||
<Text color={Color.GREY_600} className={styles.minWidth}>
|
||||
{getString('common.name')}
|
||||
</Text>
|
||||
<Text color={Color.GREY_800}>{name}</Text>
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal
|
||||
flex={{ alignItems: 'center', justifyContent: 'flex-start' }}
|
||||
margin={{ bottom: 'large' }}>
|
||||
<Text className={styles.minWidth}>{getString('common.email')}</Text>
|
||||
<Text color={Color.GREY_800}>{email}</Text>
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal
|
||||
flex={{ alignItems: 'center', justifyContent: 'flex-start' }}
|
||||
margin={{ bottom: 'large' }}>
|
||||
<Text className={styles.minWidth}>{getString('password')}</Text>
|
||||
<Text padding={{ right: 'small' }} color={Color.GREY_800}>
|
||||
*********
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
<Button
|
||||
variation={ButtonVariation.LINK}
|
||||
icon="Edit"
|
||||
text={getString('common.edit')}
|
||||
onClick={() => setEditDetails(true)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
</Page.Body>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 auto;
|
||||
}
|
||||
|
||||
.container {
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
.minWidth {
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
.input {
|
||||
margin-bottom: unset !important;
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useParams, useHistory } from 'react-router-dom'
|
||||
import { startCase, camelCase } from 'lodash'
|
||||
import { useToaster, useConfirmationDialog, Text, Color } from '@harness/uicore'
|
||||
import { Intent } from '@blueprintjs/core'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { useGetExecution, useDeleteExecution, useUpdateExecution } from 'services/pm'
|
||||
import { Settings } from '../../components/Settings/Settings'
|
||||
import routes from 'RouteDefinitions'
|
||||
|
||||
interface PathProps {
|
||||
pipeline: string
|
||||
execution: string
|
||||
}
|
||||
|
||||
interface ExecutionProps {
|
||||
name?: string
|
||||
desc?: string
|
||||
}
|
||||
|
||||
export const ExecutionSettings = () => {
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { showError, showSuccess } = useToaster()
|
||||
const { pipeline, execution } = useParams<PathProps>()
|
||||
|
||||
const [name, setName] = useState<string | undefined>('')
|
||||
const [desc, setDesc] = useState<string | undefined>('')
|
||||
|
||||
const { data, loading, error, refetch } = useGetExecution({ pipeline, execution })
|
||||
const { mutate: deleteExecution } = useDeleteExecution({ pipeline })
|
||||
const { mutate: updateExecution } = useUpdateExecution({ pipeline, execution })
|
||||
const title = `${startCase(camelCase(data?.name!.replace(/-/g, ' ')))} Settings`
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setName(data.name)
|
||||
setDesc(data.desc)
|
||||
}
|
||||
}, [data])
|
||||
|
||||
const handleUpdate = async ({ name, desc }: ExecutionProps) => {
|
||||
try {
|
||||
await updateExecution({ name, desc })
|
||||
showSuccess(getString('common.itemUpdated'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
await deleteExecution(execution)
|
||||
history.push(routes.toPipeline({ pipeline }))
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const { openDialog } = useConfirmationDialog({
|
||||
titleText: getString('common.delete'),
|
||||
contentText: <Text color={Color.GREY_800}>Are you sure you want to delete this?</Text>,
|
||||
confirmButtonText: getString('common.delete'),
|
||||
cancelButtonText: getString('common.cancel'),
|
||||
intent: Intent.DANGER,
|
||||
buttonIntent: Intent.DANGER,
|
||||
onCloseDialog: async (isConfirmed: boolean) => {
|
||||
if (isConfirmed) {
|
||||
try {
|
||||
await handleDelete()
|
||||
showSuccess(getString('common.itemDeleted'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${JSON.stringify(err)}`)
|
||||
console.error({ err })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const handleSubmit = (data: ExecutionProps): void => {
|
||||
handleUpdate(data)
|
||||
}
|
||||
|
||||
return (
|
||||
<Settings
|
||||
name={name}
|
||||
desc={desc}
|
||||
handleDelete={openDialog}
|
||||
loading={loading}
|
||||
handleSubmit={handleSubmit}
|
||||
refetch={refetch}
|
||||
title={title}
|
||||
error={error}
|
||||
/>
|
||||
)
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 auto;
|
||||
|
||||
.filterTab {
|
||||
text-align: center;
|
||||
padding: 21px;
|
||||
border-bottom: 3px solid transparent;
|
||||
|
||||
&.selected {
|
||||
border-bottom-color: var(--primary-7);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: var(--spacing-large) var(--spacing-xlarge) !important;
|
||||
border-bottom: 1px solid var(--grey-200);
|
||||
background: var(--white) !important;
|
||||
|
||||
.headerLayout {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Copyright 2021 Harness Inc. All rights reserved.
|
||||
* Use of this source code is governed by the PolyForm Shield 1.0.0 license
|
||||
* that can be found in the licenses directory at the root of this repository, also available at
|
||||
* https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
|
||||
**/
|
||||
// this is an auto-generated file, do not update this manually
|
||||
declare const styles: {
|
||||
readonly filterTab: string
|
||||
readonly header: string
|
||||
readonly headerLayout: string
|
||||
readonly root: string
|
||||
readonly selected: string
|
||||
}
|
||||
export default styles
|
@ -1,118 +0,0 @@
|
||||
import React from 'react'
|
||||
import { useParams, useHistory } from 'react-router-dom'
|
||||
import {
|
||||
Button,
|
||||
ButtonVariation,
|
||||
Container,
|
||||
Layout,
|
||||
Page,
|
||||
useModalHook,
|
||||
Formik,
|
||||
FormikForm,
|
||||
FormInput,
|
||||
useToaster
|
||||
} from '@harness/uicore'
|
||||
import { Dialog } from '@blueprintjs/core'
|
||||
import { useListExecutions, useCreateExecution, useDeleteExecution } from 'services/pm'
|
||||
import { startCase, camelCase } from 'lodash'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import Table from '../../components/Table/Table'
|
||||
import routes from 'RouteDefinitions'
|
||||
import styles from './Executions.module.scss'
|
||||
|
||||
export interface ExecutionsParams {
|
||||
pipeline: string
|
||||
}
|
||||
|
||||
interface ExecutionForm {
|
||||
name: string
|
||||
desc: string
|
||||
}
|
||||
|
||||
export const Executions: React.FC = () => {
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { showSuccess, showError } = useToaster()
|
||||
const { pipeline } = useParams<ExecutionsParams>()
|
||||
const { mutate: deleteExecution } = useDeleteExecution({ pipeline: pipeline })
|
||||
const { mutate: createExecution } = useCreateExecution({ pipeline })
|
||||
const { data: executionList, loading, error, refetch } = useListExecutions({ pipeline })
|
||||
|
||||
const title = `${startCase(camelCase(pipeline.replace(/-/g, ' ')))} ${getString('executions')}`
|
||||
|
||||
const handleCreate = async ({ name, desc }: ExecutionForm) => {
|
||||
try {
|
||||
await createExecution({ name, desc })
|
||||
showSuccess(getString('common.itemCreated'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error({ error })
|
||||
}
|
||||
}
|
||||
|
||||
const modalProps = {
|
||||
isOpen: true,
|
||||
usePortal: true,
|
||||
autoFocus: true,
|
||||
canEscapeKeyClose: true,
|
||||
canOutsideClickClose: true,
|
||||
enforceFocus: true,
|
||||
title: getString('addExecution'),
|
||||
style: { width: 400, height: 300 }
|
||||
}
|
||||
|
||||
const handleSubmit = (data: ExecutionForm): void => {
|
||||
handleCreate(data)
|
||||
hideModal()
|
||||
}
|
||||
|
||||
const onRowClick = (execution: string) => {
|
||||
history.push(routes.toPipelineExecutionSettings({ pipeline, execution }))
|
||||
}
|
||||
|
||||
const onSettingsClick = (execution: string) => {
|
||||
history.push(routes.toPipelineExecutionSettings({ pipeline, execution }))
|
||||
}
|
||||
|
||||
const [openModal, hideModal] = useModalHook(() => (
|
||||
<Dialog onClose={hideModal} {...modalProps}>
|
||||
<Container margin={{ top: 'large' }} flex={{ alignItems: 'center', justifyContent: 'space-around' }}>
|
||||
<Formik<ExecutionForm>
|
||||
initialValues={{ name: '', desc: '' }}
|
||||
formName="newExecutionForm"
|
||||
onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<FormInput.Text name="name" label={getString('common.name')} />
|
||||
<FormInput.Text name="desc" label={getString('common.description')} />
|
||||
<Button type="submit" intent="primary" width="100%">
|
||||
Create
|
||||
</Button>
|
||||
</FormikForm>
|
||||
</Formik>
|
||||
</Container>
|
||||
</Dialog>
|
||||
))
|
||||
|
||||
return (
|
||||
<Container className={styles.root} height="inherit">
|
||||
<Page.Header title={title} />
|
||||
<Layout.Horizontal spacing="large" className={styles.header}>
|
||||
<Button variation={ButtonVariation.PRIMARY} text="New Execution" icon="plus" onClick={openModal} />
|
||||
<div style={{ flex: 1 }} />
|
||||
</Layout.Horizontal>
|
||||
<Page.Body
|
||||
loading={loading}
|
||||
retryOnError={() => refetch()}
|
||||
error={(error?.data as Error)?.message || error?.message}>
|
||||
<Table
|
||||
onRowClick={onRowClick}
|
||||
refetch={refetch}
|
||||
data={executionList}
|
||||
onDelete={deleteExecution}
|
||||
onSettingsClick={onSettingsClick}
|
||||
/>
|
||||
</Page.Body>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -12,7 +12,7 @@ import {
|
||||
Layout,
|
||||
useToaster
|
||||
} from '@harness/uicore'
|
||||
import { get } from 'lodash'
|
||||
import { get } from 'lodash-es'
|
||||
import { useAPIToken } from 'hooks/useAPIToken'
|
||||
import { useOnLogin, useOnRegister } from 'services/pm'
|
||||
import { useStrings } from 'framework/strings'
|
||||
@ -43,23 +43,21 @@ export const Login: React.FC = () => {
|
||||
|
||||
if (pathname === '/login') {
|
||||
mutate(formData as unknown as void)
|
||||
.then(data => {
|
||||
setToken(get(data, 'access_token' as string))
|
||||
history.replace(routes.toPipelines())
|
||||
.then(_data => {
|
||||
setToken(get(_data, 'access_token' as string))
|
||||
history.replace(routes.toPolicyDashboard())
|
||||
})
|
||||
.catch(error => {
|
||||
showError(`Error: ${error}`)
|
||||
console.error({ error })
|
||||
})
|
||||
} else {
|
||||
mutateRegister(formData as unknown as void)
|
||||
.then(data => {
|
||||
setToken(get(data, 'access_token' as string))
|
||||
history.replace(routes.toPipelines())
|
||||
.then(_data => {
|
||||
setToken(get(_data, 'access_token' as string))
|
||||
history.replace(routes.toPolicyDashboard())
|
||||
})
|
||||
.catch(error => {
|
||||
showError(`Error: ${error}`)
|
||||
console.error({ error })
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -76,7 +74,7 @@ export const Login: React.FC = () => {
|
||||
<HarnessLogo height={25} />
|
||||
</Container>
|
||||
<Text font={{ size: 'large', weight: 'bold' }} color={Color.BLACK}>
|
||||
{pathname === '/login' ? getString('signin') : getString('signUp')}
|
||||
{pathname === '/login' ? getString('signIn') : getString('signUp')}
|
||||
</Text>
|
||||
<Text font={{ size: 'medium' }} color={Color.BLACK} margin={{ top: 'xsmall' }}>
|
||||
and get ship done.
|
||||
@ -88,10 +86,10 @@ export const Login: React.FC = () => {
|
||||
formName="loginPageForm"
|
||||
onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<FormInput.Text name="email" label={getString('common.email')} />
|
||||
<FormInput.Text name="email" label={getString('email')} />
|
||||
<FormInput.Text name="password" label={getString('password')} inputGroup={{ type: 'password' }} />
|
||||
<Button type="submit" intent="primary" width="100%">
|
||||
{pathname === '/login' ? getString('signin') : getString('signUp')}
|
||||
{pathname === '/login' ? getString('signIn') : getString('signUp')}
|
||||
</Button>
|
||||
</FormikForm>
|
||||
</Formik>
|
||||
@ -99,8 +97,8 @@ export const Login: React.FC = () => {
|
||||
|
||||
<Layout.Horizontal margin={{ top: 'xxxlarge' }} spacing="xsmall">
|
||||
<Text>{pathname === '/login' ? getString('noAccount') : getString('existingAccount')}</Text>
|
||||
<Link to={pathname === '/login' ? routes.toRegister() : routes.toLogin()}>
|
||||
{pathname === '/login' ? getString('signUp') : getString('signin')}
|
||||
<Link to={pathname === '/login' ? routes.toRegister() : routes.toSignIn()}>
|
||||
{pathname === '/login' ? getString('signUp') : getString('signIn')}
|
||||
</Link>
|
||||
</Layout.Horizontal>
|
||||
</div>
|
||||
|
@ -1,99 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useParams, useHistory } from 'react-router-dom'
|
||||
import { startCase, camelCase } from 'lodash'
|
||||
import { useToaster, useConfirmationDialog, Text, Color } from '@harness/uicore'
|
||||
import { Intent } from '@blueprintjs/core'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { useGetPipeline, useUpdatePipeline, useDeletePipeline } from 'services/pm'
|
||||
import { Settings } from '../../components/Settings/Settings'
|
||||
import routes from 'RouteDefinitions'
|
||||
|
||||
interface PathProps {
|
||||
pipeline: string
|
||||
}
|
||||
|
||||
interface PipelineProps {
|
||||
name?: string
|
||||
desc?: string
|
||||
}
|
||||
|
||||
export const PipelineSettings = () => {
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { showError, showSuccess } = useToaster()
|
||||
const { pipeline } = useParams<PathProps>()
|
||||
|
||||
const [name, setName] = useState<string | undefined>('')
|
||||
const [desc, setDesc] = useState<string | undefined>('')
|
||||
|
||||
const { data, loading, error, refetch } = useGetPipeline({ pipeline })
|
||||
const { mutate: updatePipeline } = useUpdatePipeline({ pipeline })
|
||||
const { mutate: deletePipeline } = useDeletePipeline({})
|
||||
const title = `${startCase(camelCase(data?.name!.replace(/-/g, ' ')))} Settings`
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setName(data.name)
|
||||
setDesc(data.desc)
|
||||
}
|
||||
}, [data])
|
||||
|
||||
const handleUpdate = async ({ name, desc }: PipelineProps) => {
|
||||
try {
|
||||
await updatePipeline({ name, desc })
|
||||
showSuccess(getString('common.itemUpdated'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
await deletePipeline(pipeline)
|
||||
history.push(routes.toPipelines())
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const { openDialog } = useConfirmationDialog({
|
||||
titleText: getString('common.delete'),
|
||||
contentText: <Text color={Color.GREY_800}>Are you sure you want to delete this?</Text>,
|
||||
confirmButtonText: getString('common.delete'),
|
||||
cancelButtonText: getString('common.cancel'),
|
||||
intent: Intent.DANGER,
|
||||
buttonIntent: Intent.DANGER,
|
||||
onCloseDialog: async (isConfirmed: boolean) => {
|
||||
if (isConfirmed) {
|
||||
try {
|
||||
await handleDelete()
|
||||
showSuccess(getString('common.itemDeleted'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${JSON.stringify(err)}`)
|
||||
console.error({ err })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const handleSubmit = (data: PipelineProps): void => {
|
||||
handleUpdate(data)
|
||||
}
|
||||
|
||||
return (
|
||||
<Settings
|
||||
name={name}
|
||||
desc={desc}
|
||||
handleDelete={openDialog}
|
||||
loading={loading}
|
||||
handleSubmit={handleSubmit}
|
||||
refetch={refetch}
|
||||
title={title}
|
||||
error={error}
|
||||
/>
|
||||
)
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Copyright 2021 Harness Inc. All rights reserved.
|
||||
* Use of this source code is governed by the PolyForm Shield 1.0.0 license
|
||||
* that can be found in the licenses directory at the root of this repository, also available at
|
||||
* https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
|
||||
**/
|
||||
// this is an auto-generated file, do not update this manually
|
||||
declare const styles: {
|
||||
readonly filterTab: string
|
||||
readonly header: string
|
||||
readonly headerLayout: string
|
||||
readonly root: string
|
||||
readonly selected: string
|
||||
}
|
||||
export default styles
|
@ -1,112 +0,0 @@
|
||||
import React from 'react'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import {
|
||||
Button,
|
||||
ButtonVariation,
|
||||
Container,
|
||||
Layout,
|
||||
Page,
|
||||
useModalHook,
|
||||
Formik,
|
||||
FormikForm,
|
||||
FormInput,
|
||||
useToaster
|
||||
} from '@harness/uicore'
|
||||
import { Dialog } from '@blueprintjs/core'
|
||||
import { useListPipelines, useCreatePipeline, useDeletePipeline } from 'services/pm'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import Table from '../../components/Table/Table'
|
||||
import routes from 'RouteDefinitions'
|
||||
|
||||
import styles from './Pipelines.module.scss'
|
||||
|
||||
interface PipelineForm {
|
||||
name: string
|
||||
desc: string
|
||||
}
|
||||
|
||||
export const Home: React.FC = () => {
|
||||
const { getString } = useStrings()
|
||||
const history = useHistory()
|
||||
const { showError, showSuccess } = useToaster()
|
||||
const { mutate: createPipeline } = useCreatePipeline({})
|
||||
const { mutate: deletePipeline } = useDeletePipeline({})
|
||||
const { data: pipelineList, loading, error, refetch } = useListPipelines({})
|
||||
const modalProps = {
|
||||
isOpen: true,
|
||||
usePortal: true,
|
||||
autoFocus: true,
|
||||
canEscapeKeyClose: true,
|
||||
canOutsideClickClose: true,
|
||||
enforceFocus: true,
|
||||
title: 'Add New Pipeline',
|
||||
style: { width: 400, height: 300 }
|
||||
}
|
||||
|
||||
const onRowClick = (pipeline: string) => {
|
||||
history.push(routes.toPipeline({ pipeline }))
|
||||
}
|
||||
|
||||
const onSettingsClick = (pipeline: string) => {
|
||||
history.push(routes.toPipelineSettings({ pipeline }))
|
||||
}
|
||||
|
||||
const [openModal, hideModal] = useModalHook(() => (
|
||||
<Dialog onClose={hideModal} {...modalProps}>
|
||||
<Container margin={{ top: 'large' }} flex={{ alignItems: 'center', justifyContent: 'space-around' }}>
|
||||
<Formik<PipelineForm> initialValues={{ name: '', desc: '' }} formName="newPipelineForm" onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<FormInput.Text name="name" label={getString('common.name')} />
|
||||
<FormInput.Text name="desc" label={getString('common.description')} />
|
||||
<Button type="submit" intent="primary" width="100%">
|
||||
Create
|
||||
</Button>
|
||||
</FormikForm>
|
||||
</Formik>
|
||||
</Container>
|
||||
</Dialog>
|
||||
))
|
||||
|
||||
const handleCreate = async (data: PipelineForm) => {
|
||||
const { name, desc } = data
|
||||
try {
|
||||
await createPipeline({ name, desc })
|
||||
showSuccess(getString('common.itemCreated'))
|
||||
refetch()
|
||||
} catch (err) {
|
||||
showError(`Error: ${err}`)
|
||||
console.error({ err })
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = (data: PipelineForm): void => {
|
||||
handleCreate(data)
|
||||
hideModal()
|
||||
}
|
||||
|
||||
if (error) {
|
||||
history.push(routes.toLogin())
|
||||
}
|
||||
|
||||
return (
|
||||
<Container className={styles.root} height="inherit">
|
||||
<Page.Header title={getString('pipelines')} />
|
||||
<Layout.Horizontal spacing="large" className={styles.header}>
|
||||
<Button variation={ButtonVariation.PRIMARY} text="New Pipeline" icon="plus" onClick={openModal} />
|
||||
<div style={{ flex: 1 }} />
|
||||
</Layout.Horizontal>
|
||||
<Page.Body
|
||||
loading={loading}
|
||||
retryOnError={() => refetch()}
|
||||
error={(error?.data as Error)?.message || error?.message}>
|
||||
<Table
|
||||
onRowClick={onRowClick}
|
||||
refetch={refetch}
|
||||
data={pipelineList}
|
||||
onDelete={deletePipeline}
|
||||
onSettingsClick={onSettingsClick}
|
||||
/>
|
||||
</Page.Body>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 auto;
|
||||
|
||||
.filterTab {
|
||||
text-align: center;
|
||||
padding: 21px;
|
||||
border-bottom: 3px solid transparent;
|
||||
|
||||
&.selected {
|
||||
border-bottom-color: var(--primary-7);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: var(--spacing-large) var(--spacing-xlarge) !important;
|
||||
border-bottom: 1px solid var(--grey-200);
|
||||
background: var(--white) !important;
|
||||
|
||||
.headerLayout {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,94 +1,91 @@
|
||||
import React, { useRef, useState, useCallback } from "react";
|
||||
import React, { useRef, useState, useCallback } from 'react'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import styles from "./Register.module.scss";
|
||||
import { useOnRegister } from 'services/pm'
|
||||
import routes from 'RouteDefinitions'
|
||||
|
||||
import Link from "../../components/Link/Link";
|
||||
import Input from "../../components/Input/input";
|
||||
import Button from "../../components/Button/button";
|
||||
import logo from "../../logo.svg"
|
||||
import Link from '../../components/Link/Link'
|
||||
import Input from '../../components/Input/input'
|
||||
import Button from '../../components/Button/button'
|
||||
import logo from '../../logo.svg'
|
||||
import styles from './Register.module.scss'
|
||||
|
||||
// Renders the Register page.
|
||||
export const Register = () => {
|
||||
const history = useHistory()
|
||||
const [error, setError] = useState(null);
|
||||
const [fullname, setFullname] = useState('')
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const { mutate } = useOnRegister({})
|
||||
const history = useHistory()
|
||||
const [error, setError] = useState(null)
|
||||
const [fullname, setFullname] = useState('')
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const { mutate } = useOnRegister({})
|
||||
|
||||
const handleRegister = useCallback(() => {
|
||||
const formData = new FormData()
|
||||
|
||||
formData.append("fullname", fullname);
|
||||
formData.append("password", password);
|
||||
formData.append("username", username);
|
||||
|
||||
mutate(formData)
|
||||
.then(() => {
|
||||
history.replace(routes.toLogin())
|
||||
})
|
||||
.catch(error => {
|
||||
// TODO: Use toaster to show error
|
||||
// eslint-disable-next-line no-console
|
||||
console.error({ error })
|
||||
setError(error);
|
||||
})
|
||||
}, [mutate, username, password, fullname, history])
|
||||
const handleRegister = useCallback(() => {
|
||||
const formData = new FormData()
|
||||
|
||||
const alert =
|
||||
error && error.message ? (
|
||||
<div class="alert">{error.message}</div>
|
||||
) : undefined;
|
||||
formData.append('fullname', fullname)
|
||||
formData.append('password', password)
|
||||
formData.append('username', username)
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.logo}>
|
||||
<img src={logo} />
|
||||
</div>
|
||||
<h2>Sign up for a new account</h2>
|
||||
{alert}
|
||||
<div className={styles.field}>
|
||||
<label>Full Name</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="fullname"
|
||||
placeholder="Full Name"
|
||||
className={styles.input}
|
||||
onChange={e => setFullname(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.field}>
|
||||
<label>Email</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="Email"
|
||||
className={styles.input}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.field}>
|
||||
<label>Password</label>
|
||||
<Input
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
className={styles.input}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Button onClick={handleRegister} className={styles.submit}>
|
||||
Sign Up
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<span>
|
||||
Already have an account? <Link href="/login">Sign In</Link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
mutate(formData)
|
||||
.then(() => {
|
||||
history.replace(routes.toLogin())
|
||||
})
|
||||
.catch(error => {
|
||||
// TODO: Use toaster to show error
|
||||
// eslint-disable-next-line no-console
|
||||
console.error({ error })
|
||||
setError(error)
|
||||
})
|
||||
}, [mutate, username, password, fullname, history])
|
||||
|
||||
const alert = error && error.message ? <div class="alert">{error.message}</div> : undefined
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.logo}>
|
||||
<img src={logo} />
|
||||
</div>
|
||||
<h2>Sign up for a new account</h2>
|
||||
{alert}
|
||||
<div className={styles.field}>
|
||||
<label>Full Name</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="fullname"
|
||||
placeholder="Full Name"
|
||||
className={styles.input}
|
||||
onChange={e => setFullname(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.field}>
|
||||
<label>Email</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="Email"
|
||||
className={styles.input}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.field}>
|
||||
<label>Password</label>
|
||||
<Input
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
className={styles.input}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Button onClick={handleRegister} className={styles.submit}>
|
||||
Sign Up
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<span>
|
||||
Already have an account? <Link href="/login">Sign In</Link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export const SignIn: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Layout.Vertical>
|
||||
<h1>{getString('signin')}</h1>
|
||||
<h1>{getString('signIn')}</h1>
|
||||
<Container>
|
||||
<Layout.Horizontal>
|
||||
<Text>Username</Text>
|
||||
@ -55,7 +55,7 @@ export const SignIn: React.FC = () => {
|
||||
</Layout.Horizontal>
|
||||
</Container>
|
||||
<Container>
|
||||
<Button text={getString('signin')} onClick={() => onLogin()} />
|
||||
<Button text={getString('signIn')} onClick={() => onLogin()} />
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
)
|
||||
|
@ -5,7 +5,7 @@ export const getConfig = (str: string): string => {
|
||||
// NOTE: Replace /^pm\// with your service prefixes when running in standalone mode
|
||||
// I.e: 'pm/api/v1' -> 'api/v1' (standalone)
|
||||
// -> 'pm/api/v1' (embedded inside Harness platform)
|
||||
if (window.APP_RUN_IN_STANDALONE_MODE) {
|
||||
if (window.STRIP_SCM_PREFIX) {
|
||||
str = str.replace(/^pm\//, '')
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { queryByAttribute } from '@testing-library/react'
|
||||
import { compile } from 'path-to-regexp'
|
||||
import { createMemoryHistory } from 'history'
|
||||
import { Router, Route, Switch, useLocation, useHistory } from 'react-router-dom'
|
||||
import { ModalProvider } from '@harness/uicore'
|
||||
import { ModalProvider } from '@harness/use-modal'
|
||||
import qs from 'qs'
|
||||
import { enableMapSet } from 'immer'
|
||||
import { StringsContext } from 'framework/strings'
|
||||
|
109
web/yarn.lock
109
web/yarn.lock
@ -4276,21 +4276,22 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/yup/-/yup-0.29.14.tgz#754f1dccedcc66fc2bbe290c27f5323b407ceb00"
|
||||
integrity sha512-Ynb/CjHhE/Xp/4bhHmQC4U1Ox+I2OpfRYF3dnNgQqn1cHa6LK3H1wJMNPT02tSVZA6FYuXE2ITORfbnb6zBCSA==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.22.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
|
||||
integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==
|
||||
"@typescript-eslint/eslint-plugin@^5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz#c0a480d05211660221eda963cc844732fe9b1714"
|
||||
integrity sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.33.0"
|
||||
"@typescript-eslint/scope-manager" "4.33.0"
|
||||
debug "^4.3.1"
|
||||
"@typescript-eslint/scope-manager" "5.33.1"
|
||||
"@typescript-eslint/type-utils" "5.33.1"
|
||||
"@typescript-eslint/utils" "5.33.1"
|
||||
debug "^4.3.4"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.1.8"
|
||||
regexpp "^3.1.0"
|
||||
semver "^7.3.5"
|
||||
ignore "^5.2.0"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@^4.0.1":
|
||||
"@typescript-eslint/experimental-utils@^4.0.1":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd"
|
||||
integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==
|
||||
@ -4302,15 +4303,15 @@
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.22.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899"
|
||||
integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==
|
||||
"@typescript-eslint/parser@^5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.1.tgz#e4b253105b4d2a4362cfaa4e184e2d226c440ff3"
|
||||
integrity sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.33.0"
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/typescript-estree" "4.33.0"
|
||||
debug "^4.3.1"
|
||||
"@typescript-eslint/scope-manager" "5.33.1"
|
||||
"@typescript-eslint/types" "5.33.1"
|
||||
"@typescript-eslint/typescript-estree" "5.33.1"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.33.0":
|
||||
version "4.33.0"
|
||||
@ -4320,11 +4321,33 @@
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/visitor-keys" "4.33.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz#8d31553e1b874210018ca069b3d192c6d23bc493"
|
||||
integrity sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.33.1"
|
||||
"@typescript-eslint/visitor-keys" "5.33.1"
|
||||
|
||||
"@typescript-eslint/type-utils@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz#1a14e94650a0ae39f6e3b77478baff002cec4367"
|
||||
integrity sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "5.33.1"
|
||||
debug "^4.3.4"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/types@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
|
||||
integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
|
||||
|
||||
"@typescript-eslint/types@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.1.tgz#3faef41793d527a519e19ab2747c12d6f3741ff7"
|
||||
integrity sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
|
||||
@ -4338,6 +4361,31 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz#a573bd360790afdcba80844e962d8b2031984f34"
|
||||
integrity sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.33.1"
|
||||
"@typescript-eslint/visitor-keys" "5.33.1"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.1.tgz#171725f924fe1fe82bb776522bb85bc034e88575"
|
||||
integrity sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.33.1"
|
||||
"@typescript-eslint/types" "5.33.1"
|
||||
"@typescript-eslint/typescript-estree" "5.33.1"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
|
||||
@ -4346,6 +4394,14 @@
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.33.1":
|
||||
version "5.33.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz#0155c7571c8cd08956580b880aea327d5c34a18b"
|
||||
integrity sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.33.1"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@urql/core@>=2.3.6", "@urql/core@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@urql/core/-/core-2.6.1.tgz#c10ee972c5e81df6d7bf1e778ef1b5d30e2906e5"
|
||||
@ -8198,6 +8254,11 @@ eslint-visitor-keys@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||
|
||||
eslint-visitor-keys@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@^7.27.0:
|
||||
version "7.32.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
|
||||
@ -9350,7 +9411,7 @@ globby@11.0.3:
|
||||
merge2 "^1.3.0"
|
||||
slash "^3.0.0"
|
||||
|
||||
globby@^11.0.1, globby@^11.0.2, globby@^11.0.3:
|
||||
globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
|
||||
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
|
||||
@ -10104,7 +10165,7 @@ ignore@^4.0.3, ignore@^4.0.6:
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||
|
||||
ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0:
|
||||
ignore@^5.1.4, ignore@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
|
||||
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
|
||||
@ -15305,7 +15366,7 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1, regexp.prototype.f
|
||||
define-properties "^1.1.3"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
regexpp@^3.1.0:
|
||||
regexpp@^3.1.0, regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
@ -15940,7 +16001,7 @@ semver@7.0.0, semver@~7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
|
||||
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
|
||||
|
||||
semver@7.3.7, semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
|
||||
semver@7.3.7, semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
|
||||
version "7.3.7"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
||||
@ -17540,7 +17601,7 @@ typescript@^2.7.2:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
||||
integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
|
||||
|
||||
typescript@^4.2.4:
|
||||
typescript@^4.7.4:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
|
Loading…
Reference in New Issue
Block a user