Skip to content

Commit b2df2ac

Browse files
Merge pull request #1723 from rocket-admin/connection-string-mode
Connection string mode
2 parents 3daeb51 + e538655 commit b2df2ac

7 files changed

Lines changed: 306 additions & 173 deletions

File tree

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"chart.js": "^4.5.1",
4747
"chartjs-adapter-date-fns": "^3.0.0",
4848
"color-string": "^2.0.1",
49+
"connection-string-parser": "^1.0.4",
4950
"convert": "^5.12.0",
5051
"date-fns": "^4.1.0",
5152
"ipaddr.js": "^2.2.0",

frontend/src/app/components/connect-db/connect-db.component.css

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,28 @@
2424
}
2525
}
2626

27-
.credentials-fieldset {
27+
:host ::ng-deep .credentials-fieldset {
2828
display: grid;
2929
grid-template-columns: subgrid;
3030
grid-template-rows: subgrid;
3131
grid-column: 1 / span 4;
32-
grid-row: 5 / span 4;
32+
grid-row: 6 / span 4;
3333
}
3434

35+
:host ::ng-deep .connectForm__typeSwitch + ndc-dynamic + .credentials-fieldset {
36+
grid-row: 4 / span 4;
37+
}
38+
39+
40+
3541
@media (width <= 600px) {
36-
.credentials-fieldset {
42+
:host ::ng-deep .credentials-fieldset {
3743
display: flex;
3844
flex-direction: column;
3945
}
4046
}
4147

42-
.credentials-fieldset-no-warning {
48+
/* :host ::ng-deep .credentials-fieldset-no-warning {
4349
display: grid;
4450
grid-template-columns: subgrid;
4551
grid-template-rows: subgrid;
@@ -48,11 +54,11 @@
4854
}
4955
5056
@media (width <= 600px) {
51-
.credentials-fieldset-no-warning {
57+
:host ::ng-deep .credentials-fieldset-no-warning {
5258
display: flex;
5359
flex-direction: column;
5460
}
55-
}
61+
} */
5662

5763
.mat-h1 {
5864
margin-top: 2vw;
@@ -87,7 +93,8 @@
8793
}
8894

8995
.connectForm__ipAlert {
90-
--alert-margin: 0;
96+
--alert-margin: 0 !important;
97+
margin-bottom: 12px;
9198
}
9299

93100
.connectForm__title {
@@ -103,11 +110,11 @@
103110
grid-column: 1 / span 4;
104111
}
105112

106-
.connectForm__typeSwitch {
113+
.connectForm__toggle {
107114
margin-bottom: 12px;
108115
}
109116

110-
.connectForm__typeSwitch ::ng-deep .mat-button-toggle-checked {
117+
.connectForm__toggle ::ng-deep .mat-button-toggle-checked {
111118
background-color: rgba(0, 0, 0, 0.08) !important;
112119
}
113120

@@ -200,6 +207,21 @@
200207
padding: 8px 12px;
201208
}
202209

210+
.connectForm__connectionString {
211+
display: flex;
212+
align-items: flex-start;
213+
gap: 12px;
214+
}
215+
216+
.connectForm__connectionString ::ng-deep .mat-mdc-text-field-wrapper {
217+
padding-right: 80px;
218+
}
219+
220+
.connectForm__connectionString button {
221+
margin-top: 4px;
222+
margin-left: -80px;
223+
}
224+
203225
.agent-token {
204226
display: flex;
205227
margin-top: 32px;

frontend/src/app/components/connect-db/connect-db.component.html

Lines changed: 48 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ <h1 class="mat-h1 connectForm__fullLine">
3838
</mat-select>
3939
</mat-form-field>
4040

41-
<div class="connectForm__fullLine">
41+
<div class="connectForm__fullLine connectForm__toggle connectForm__typeSwitch">
4242
<mat-button-toggle-group name="connectionType"
4343
data-testid="connection-type-toggle"
44-
class="connectForm__typeSwitch"
4544
[disabled]="submitting || db.isTestConnection || db.type === 'dynamodb'"
4645
[(ngModel)]="db.connectionType">
4746
<mat-button-toggle value="direct">Direct connection</mat-button-toggle>
@@ -51,7 +50,7 @@ <h1 class="mat-h1 connectForm__fullLine">
5150

5251
<div *ngIf="db && db.connectionType === 'direct' && !db.isTestConnection && isSaas && db.type !== 'dynamodb'"
5352
data-testid="direct-connection-warning"
54-
class="connectForm__fullLine">
53+
class="connectForm__fullLine connectForm__warningMessage">
5554
<div *ngIf="connectionID; else warningAlert" class="warningMessage">
5655
<mat-icon class="warningMessage__icon">warning_amber</mat-icon>
5756
<div class="mat-body-1">
@@ -72,156 +71,53 @@ <h1 class="mat-h1 connectForm__fullLine">
7271
</ng-template>
7372
</div>
7473

75-
<app-mysql-credentials-form *ngIf="db.type === 'mysql' && db.connectionType === 'direct'"
76-
[ngClass]="{
77-
'credentials-fieldset': !db.isTestConnection,
78-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
79-
}"
80-
[connection]="db"
81-
[submitting]="submitting"
82-
[accessLevel]="accessLevel"
83-
[masterKey]="masterKey"
84-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
85-
(switchToAgent)="switchToAgent()"
86-
(masterKeyChange)="handleMasterKeyChange($event)">
87-
</app-mysql-credentials-form>
88-
89-
<app-postgres-credentials-form *ngIf="db.type === 'postgres' && db.connectionType === 'direct'"
90-
[ngClass]="{
91-
'credentials-fieldset': !db.isTestConnection,
92-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
93-
}"
94-
[connection]="db"
95-
[submitting]="submitting"
96-
[accessLevel]="accessLevel"
97-
[masterKey]="masterKey"
98-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
99-
(switchToAgent)="switchToAgent"
100-
(masterKeyChange)="handleMasterKeyChange($event)">
101-
</app-postgres-credentials-form>
102-
103-
<app-mongodb-credentials-form *ngIf="db.type === 'mongodb' && db.connectionType === 'direct'"
104-
[ngClass]="{
105-
'credentials-fieldset': !db.isTestConnection,
106-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
107-
}"
108-
[connection]="db"
109-
[submitting]="submitting"
110-
[accessLevel]="accessLevel"
111-
[masterKey]="masterKey"
112-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
113-
(switchToAgent)="switchToAgent"
114-
(masterKeyChange)="handleMasterKeyChange($event)">
115-
</app-mongodb-credentials-form>
116-
117-
<app-dynamodb-credentials-form *ngIf="db.type === 'dynamodb' && db.connectionType === 'direct'"
118-
class="credentials-fieldset-no-warning"
119-
[connection]="db"
120-
[submitting]="submitting"
121-
[accessLevel]="accessLevel"
122-
[masterKey]="masterKey"
123-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
124-
(switchToAgent)="switchToAgent"
125-
(masterKeyChange)="handleMasterKeyChange($event)">
126-
</app-dynamodb-credentials-form>
127-
128-
<app-cassandra-credentials-form *ngIf="db.type === 'cassandra' && db.connectionType === 'direct'"
129-
[ngClass]="{
130-
'credentials-fieldset': !db.isTestConnection,
131-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
132-
}"
133-
[connection]="db"
134-
[submitting]="submitting"
135-
[accessLevel]="accessLevel"
136-
[masterKey]="masterKey"
137-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
138-
(switchToAgent)="switchToAgent"
139-
(masterKeyChange)="handleMasterKeyChange($event)">
140-
</app-cassandra-credentials-form>
141-
142-
<app-oracledb-credentials-form *ngIf="db.type === 'oracledb' && db.connectionType === 'direct'"
143-
[ngClass]="{
144-
'credentials-fieldset': !db.isTestConnection,
145-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
146-
}"
147-
[connection]="db"
148-
[submitting]="submitting"
149-
[accessLevel]="accessLevel"
150-
[masterKey]="masterKey"
151-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
152-
(switchToAgent)="switchToAgent"
153-
(masterKeyChange)="handleMasterKeyChange($event)">
154-
</app-oracledb-credentials-form>
155-
156-
<app-mssql-credentials-form *ngIf="db.type === 'mssql' && db.connectionType === 'direct'"
157-
[ngClass]="{
158-
'credentials-fieldset': !db.isTestConnection,
159-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
160-
}"
161-
[connection]="db"
162-
[submitting]="submitting"
163-
[accessLevel]="accessLevel"
164-
[masterKey]="masterKey"
165-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
166-
(switchToAgent)="switchToAgent"
167-
(masterKeyChange)="handleMasterKeyChange($event)">
168-
</app-mssql-credentials-form>
169-
170-
<app-redis-credentials-form *ngIf="db.type === 'redis' && db.connectionType === 'direct'"
171-
[ngClass]="{
172-
'credentials-fieldset': !db.isTestConnection,
173-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
174-
}"
175-
[connection]="db"
176-
[submitting]="submitting"
177-
[accessLevel]="accessLevel"
178-
[masterKey]="masterKey"
179-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
180-
(switchToAgent)="switchToAgent"
181-
(masterKeyChange)="handleMasterKeyChange($event)">
182-
</app-redis-credentials-form>
183-
184-
<app-elastic-credentials-form *ngIf="db.type === 'elasticsearch' && db.connectionType === 'direct'"
185-
[ngClass]="{
186-
'credentials-fieldset': !db.isTestConnection,
187-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
188-
}"
189-
[connection]="db"
190-
[submitting]="submitting"
191-
[accessLevel]="accessLevel"
192-
[masterKey]="masterKey"
193-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
194-
(switchToAgent)="switchToAgent"
195-
(masterKeyChange)="handleMasterKeyChange($event)">
196-
</app-elastic-credentials-form>
197-
198-
<app-clickhouse-credentials-form *ngIf="db.type === 'clickhouse' && db.connectionType === 'direct'"
199-
[ngClass]="{
200-
'credentials-fieldset': !db.isTestConnection,
201-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
202-
}"
203-
[connection]="db"
204-
[submitting]="submitting"
205-
[accessLevel]="accessLevel"
206-
[masterKey]="masterKey"
207-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
208-
(switchToAgent)="switchToAgent()"
209-
(masterKeyChange)="handleMasterKeyChange($event)">
210-
</app-clickhouse-credentials-form>
74+
@if (db.connectionType === 'direct' && !db.id) {
75+
<div class="connectForm__fullLine connectForm__connectionString">
76+
<mat-form-field appearance="outline" style="width: 100%">
77+
<mat-label>Connection string</mat-label>
78+
<input matInput name="connectionString"
79+
#connectionStringInput="ngModel"
80+
data-testid="connection-string-input"
81+
placeholder="e.g. postgresql://user:password@host:5432/dbname"
82+
connectionStringValidator
83+
[disabled]="submitting"
84+
[(ngModel)]="connectionString">
85+
<mat-hint>Paste your database connection URI to auto-fill credentials</mat-hint>
86+
@if (connectionStringInput.errors?.invalidConnectionStringFormat) {
87+
<mat-error>Invalid format. Expected: scheme://user:password@host:port/database</mat-error>
88+
}
89+
@if (connectionStringInput.errors?.unsupportedScheme) {
90+
<mat-error>Unsupported scheme "{{ connectionStringInput.errors?.unsupportedScheme }}"</mat-error>
91+
}
92+
@if (connectionStringInput.errors?.invalidConnectionString) {
93+
<mat-error>Failed to parse connection string</mat-error>
94+
}
95+
</mat-form-field>
96+
<button type="button" mat-button color="primary"
97+
class="connectForm__connectionStringApplyButton"
98+
data-testid="connection-string-apply-button"
99+
[disabled]="submitting || !connectionString.trim() || connectionStringInput.invalid"
100+
(click)="applyConnectionString()">
101+
Apply
102+
</button>
103+
</div>
104+
}
211105

212-
<app-db2-credentials-form *ngIf="db.type === 'ibmdb2' && db.connectionType === 'direct'"
213-
[ngClass]="{
214-
'credentials-fieldset': !db.isTestConnection,
215-
'credentials-fieldset-no-warning': db.isTestConnection || !isSaas
216-
}"
217-
[connection]="db"
218-
[submitting]="submitting"
219-
[accessLevel]="accessLevel"
220-
[masterKey]="masterKey"
221-
[readonly]="(accessLevel === 'readonly' || db.isTestConnection) && db.id"
222-
(switchToAgent)="switchToAgent"
223-
(masterKeyChange)="handleMasterKeyChange($event)">
224-
</app-db2-credentials-form>
106+
@if (db.connectionType === 'direct') {
107+
<ndc-dynamic
108+
[ndcDynamicComponent]="credentialsFormComponent"
109+
[ndcDynamicInputs]="{
110+
connection: db,
111+
submitting: submitting,
112+
accessLevel: accessLevel,
113+
masterKey: masterKey,
114+
readonly: !!((accessLevel === 'readonly' || db.isTestConnection) && db.id)
115+
}"
116+
[ndcDynamicOutputs]="credentialsFormOutputs"
117+
[ndcDynamicAttributes]="credentialsFormAttributes"
118+
></ndc-dynamic>
119+
}
120+
225121

226122
<div *ngIf="db.connectionType === 'agent'" class="connectForm__fullLine instruction">
227123

0 commit comments

Comments
 (0)