From f93d678daebcf4c1424d6c309d969cf8150eb4de Mon Sep 17 00:00:00 2001
From: Yi Cai
Date: Fri, 19 Aug 2022 13:07:51 -0400
Subject: [PATCH] feat: make https repo credentials editable in the UI (#9108)
(#9782)
* fix: missing actions (#10327) (#10359)
Signed-off-by: CI
Signed-off-by: CI
Signed-off-by: Yi Cai
* chore: infer managed resources health from redis instead of storing it in CRD (#10191)
* chore: infer managed resources health from redis instead of storing it in CRD
Signed-off-by: Alexander Matyushentsev
* apply reviewer notes
Signed-off-by: Alexander Matyushentsev
Signed-off-by: Alexander Matyushentsev
Signed-off-by: Yi Cai
* fix: Add logic to handle for fileHandle.Close() (#9963) (#10361)
Signed-off-by: xin.li
Signed-off-by: xin.li
Signed-off-by: Yi Cai
* docs: fix typo in upgrade notes (#10377)
Signed-off-by: Xijun Dai
Signed-off-by: Xijun Dai
Signed-off-by: Yi Cai
* fix: add space before prompt in CLI (#10362)
Signed-off-by: xin.li
Signed-off-by: xin.li
Signed-off-by: Yi Cai
* docs: fix indentation of example AppProject in 'Sync Windows' documentation (#10388)
Signed-off-by: Yi Cai
* fix: Correctly assume cluster-scoped resources to be self-referenced (#10390)
Signed-off-by: jannfis
Signed-off-by: jannfis
Signed-off-by: Yi Cai
* ui-make-https-repo-credential-editable
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Minor format fix
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Minor fix for unclickable input field
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Updates for comments
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* ui-make-https-repo-credential-editable
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Minor format fix
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Minor fix for unclickable input field
Signed-off-by: ciiay
Signed-off-by: Yi Cai
* Updates for comments
Signed-off-by: ciiay
Signed-off-by: Yi Cai
Signed-off-by: CI
Signed-off-by: Yi Cai
Signed-off-by: Alexander Matyushentsev
Signed-off-by: xin.li
Signed-off-by: Xijun Dai
Signed-off-by: jannfis
Signed-off-by: ciiay
Co-authored-by: Michael Crenshaw
Co-authored-by: Alexander Matyushentsev
Co-authored-by: my-git9
Co-authored-by: Xijun Dai
Co-authored-by: Jun Duan
Co-authored-by: jannfis
---
.../components/repo-details/repo-details.tsx | 87 ++++
.../components/repos-list/repos-list.scss | 7 +
.../components/repos-list/repos-list.tsx | 465 +++++++++++-------
.../editable-panel/editable-panel.scss | 6 +-
ui/src/app/shared/models.ts | 9 +
ui/src/app/shared/services/repo-service.ts | 31 ++
6 files changed, 413 insertions(+), 192 deletions(-)
create mode 100644 ui/src/app/settings/components/repo-details/repo-details.tsx
diff --git a/ui/src/app/settings/components/repo-details/repo-details.tsx b/ui/src/app/settings/components/repo-details/repo-details.tsx
new file mode 100644
index 0000000000000..df850a927e261
--- /dev/null
+++ b/ui/src/app/settings/components/repo-details/repo-details.tsx
@@ -0,0 +1,87 @@
+import * as React from 'react';
+import {FormField} from 'argo-ui';
+import {FormApi, Text} from 'react-form';
+import {EditablePanel, EditablePanelItem} from '../../../shared/components';
+import * as models from '../../../shared/models';
+import {NewHTTPSRepoParams} from '../repos-list/repos-list';
+
+export const RepoDetails = (props: {repo: models.Repository; save?: (params: NewHTTPSRepoParams) => Promise}) => {
+ const {repo, save} = props;
+ const FormItems = (repository: models.Repository): EditablePanelItem[] => {
+ const items: EditablePanelItem[] = [
+ {
+ title: 'Type',
+ view: repository.type
+ },
+ {
+ title: 'Repository URL',
+ view: repository.repo
+ },
+ {
+ title: 'Username (optional)',
+ view: repository.username || '',
+ edit: (formApi: FormApi) =>
+ },
+ {
+ title: 'Password (optional)',
+ view: repository.username ? '******' : '',
+ edit: (formApi: FormApi) =>
+ }
+ ];
+
+ if (repository.name) {
+ items.splice(1, 0, {
+ title: 'NAME',
+ view: repository.name
+ });
+ }
+
+ if (repository.project) {
+ items.splice(repository.name ? 2 : 1, 0, {
+ title: 'Project',
+ view: repository.project
+ });
+ }
+
+ if (repository.proxy) {
+ items.push({
+ title: 'Proxy (optional)',
+ view: repository.proxy
+ });
+ }
+
+ return items;
+ };
+
+ const newRepo = {
+ type: repo.type,
+ name: repo.name || '',
+ url: repo.repo,
+ username: repo.username || '',
+ password: repo.password || '',
+ tlsClientCertData: repo.tlsClientCertData || '',
+ tlsClientCertKey: repo.tlsClientCertKey || '',
+ insecure: repo.insecure || false,
+ enableLfs: repo.enableLfs || false,
+ proxy: repo.proxy || '',
+ project: repo.project || ''
+ };
+
+ return (
+ ({
+ username: !input.username && input.password && 'Username is required if password is given.',
+ password: !input.password && input.username && 'Password is required if username is given.'
+ })}
+ save={async input => {
+ const params: NewHTTPSRepoParams = {...newRepo};
+ params.username = input.username || '';
+ params.password = input.password || '';
+ save(params);
+ }}
+ title='CONNECTED REPOSITORY'
+ items={FormItems(repo)}
+ />
+ );
+};
diff --git a/ui/src/app/settings/components/repos-list/repos-list.scss b/ui/src/app/settings/components/repos-list/repos-list.scss
index 9b5b30b38e02b..0994a8c97a523 100644
--- a/ui/src/app/settings/components/repos-list/repos-list.scss
+++ b/ui/src/app/settings/components/repos-list/repos-list.scss
@@ -28,6 +28,13 @@
}
.argo-table-list {
+ .item-clickable {
+ cursor: pointer;
+
+ &:hover {
+ box-shadow: 1px 2px 3px rgba($argo-color-gray-9, 0.1), 0 0 0 1px rgba($argo-color-teal-5, 0.5);
+ }
+ }
.argo-dropdown {
float: right;
}
diff --git a/ui/src/app/settings/components/repos-list/repos-list.tsx b/ui/src/app/settings/components/repos-list/repos-list.tsx
index 7feec8daa027b..9005728f8d3af 100644
--- a/ui/src/app/settings/components/repos-list/repos-list.tsx
+++ b/ui/src/app/settings/components/repos-list/repos-list.tsx
@@ -8,6 +8,7 @@ import {CheckboxField, ConnectionStateIcon, DataLoader, EmptyState, ErrorNotific
import {AppContext} from '../../../shared/context';
import * as models from '../../../shared/models';
import {services} from '../../../shared/services';
+import {RepoDetails} from '../repo-details/repo-details';
require('./repos-list.scss');
@@ -22,7 +23,7 @@ interface NewSSHRepoParams {
project?: string;
}
-interface NewHTTPSRepoParams {
+export interface NewHTTPSRepoParams {
type: string;
name: string;
url: string;
@@ -86,6 +87,8 @@ export class ReposList extends React.Component<
{
connecting: boolean;
method: string;
+ currentRepo: models.Repository;
+ displayEditPanel: boolean;
}
> {
public static contextTypes = {
@@ -103,7 +106,9 @@ export class ReposList extends React.Component<
super(props);
this.state = {
connecting: false,
- method: ConnectionMethod.SSH
+ method: ConnectionMethod.SSH,
+ currentRepo: null,
+ displayEditPanel: false
};
}
@@ -118,10 +123,10 @@ export class ReposList extends React.Component<
)}
items={[ConnectionMethod.SSH, ConnectionMethod.HTTPS, ConnectionMethod.GITHUBAPP].map(
- (type: ConnectionMethod.SSH | ConnectionMethod.HTTPS | ConnectionMethod.GITHUBAPP) => ({
- title: type.toUpperCase(),
+ (connectMethod: ConnectionMethod.SSH | ConnectionMethod.HTTPS | ConnectionMethod.GITHUBAPP) => ({
+ title: connectMethod.toUpperCase(),
action: () => {
- onSelection(type);
+ onSelection(connectMethod);
const formState = this.formApi.getFormState();
this.formApi.setFormState({
...formState,
@@ -151,6 +156,7 @@ export class ReposList extends React.Component<
return {
url: (!httpsValues.url && 'Repository URL is required') || (this.credsTemplate && !this.isHTTPSUrl(httpsValues.url) && 'Not a valid HTTPS URL'),
name: httpsValues.type === 'helm' && !httpsValues.name && 'Name is required',
+ username: !httpsValues.username && httpsValues.password && 'Username is required if password is given.',
password: !httpsValues.password && httpsValues.username && 'Password is required if username is given.',
tlsClientCertKey: !httpsValues.tlsClientCertKey && httpsValues.tlsClientCertData && 'TLS client cert key is required if TLS client cert is given.'
};
@@ -165,6 +171,42 @@ export class ReposList extends React.Component<
}
}
+ private SlidingPanelHeader() {
+ return (
+ <>
+ {this.showConnectRepo && (
+ <>
+ {' '}
+ {' '}
+
+ >
+ )}
+ {this.state.displayEditPanel && (
+
+ )}
+ >
+ );
+ }
+
private onSubmitForm() {
switch (this.state.method) {
case ConnectionMethod.SSH:
@@ -215,7 +257,10 @@ export class ReposList extends React.Component<
{repos.map(repo => (
-
+
(this.isRepoUpdatable(repo) ? this.displayEditSliding(repo) : null)}>
@@ -299,201 +344,217 @@ export class ReposList extends React.Component<
(this.showConnectRepo = false)}
- header={
- <>
- {' '}
- {' '}
-
- >
- }>
- {this.ConnectRepoFormButton(this.state.method, method => {
- this.setState({method});
- })}
- services.projects.list('items.metadata.name').then(projects => projects.map(proj => proj.metadata.name).sort())}>
- {projects => (
-