Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
truenas-rk3588
webui
Commits
9ac541d7
Commit
9ac541d7
authored
3 years ago
by
Evgeny Stepanovych
Browse files
Options
Download
Email Patches
Plain Diff
NAS-113430: Improving type safety
parent
0af5d736
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
src/app/components/common/topbar/topbar.component.ts
+0
-3
src/app/components/common/topbar/topbar.component.ts
src/app/enums/fibre-channel-port-mode.enum.ts
+5
-0
src/app/enums/fibre-channel-port-mode.enum.ts
src/app/interfaces/api-directory.interface.ts
+13
-15
src/app/interfaces/api-directory.interface.ts
src/app/interfaces/cloudsync-credential.interface.ts
+6
-0
src/app/interfaces/cloudsync-credential.interface.ts
src/app/interfaces/fibre-channel-port.interface.ts
+8
-0
src/app/interfaces/fibre-channel-port.interface.ts
src/app/pages/api-keys/api-keys.component.ts
+1
-2
src/app/pages/api-keys/api-keys.component.ts
src/app/pages/applications/catalog/catalog.component.ts
+1
-2
src/app/pages/applications/catalog/catalog.component.ts
src/app/pages/applications/chart-releases/chart-releases.component.ts
+5
-8
...s/applications/chart-releases/chart-releases.component.ts
src/app/pages/applications/docker-images/docker-images.component.ts
+0
-1
...ges/applications/docker-images/docker-images.component.ts
src/app/pages/applications/pod-logs/pod-logs.component.ts
+2
-3
src/app/pages/applications/pod-logs/pod-logs.component.ts
src/app/pages/applications/pod-shell/pod-shell.component.ts
+2
-3
src/app/pages/applications/pod-shell/pod-shell.component.ts
src/app/pages/common/entity/entity-dialog/dialog-form-configuration.interface.ts
+5
-9
...tity/entity-dialog/dialog-form-configuration.interface.ts
src/app/pages/common/entity/entity-dialog/entity-dialog.component.ts
+2
-10
...es/common/entity/entity-dialog/entity-dialog.component.ts
src/app/pages/common/entity/utils.ts
+18
-5
src/app/pages/common/entity/utils.ts
src/app/pages/credentials/backup-credentials/forms/cloud-credentials-form.component.ts
+7
-3
...kup-credentials/forms/cloud-credentials-form.component.ts
src/app/pages/credentials/certificates-dash/certificates-dash.component.ts
+20
-21
...dentials/certificates-dash/certificates-dash.component.ts
src/app/pages/credentials/certificates-dash/forms/acmedns-form.component.ts
+1
-2
...entials/certificates-dash/forms/acmedns-form.component.ts
src/app/pages/credentials/certificates-dash/forms/ca-edit.component.ts
+1
-2
.../credentials/certificates-dash/forms/ca-edit.component.ts
src/app/pages/data-protection/components/data-protection-dashboard/data-protection-dashboard.component.ts
+32
-32
...otection-dashboard/data-protection-dashboard.component.ts
src/app/pages/network/forms/interfaces-form.component.ts
+1
-2
src/app/pages/network/forms/interfaces-form.component.ts
with
130 additions
and
123 deletions
+130
-123
src/app/components/common/topbar/topbar.component.ts
View file @
9ac541d7
...
...
@@ -646,7 +646,6 @@ export class TopbarComponent extends ViewControllerComponent implements OnInit,
},
},
],
parent
:
this
,
customSubmit
:
(
entityDialog
:
EntityDialogComponent
)
=>
{
entityDialog
.
dialogRef
.
close
();
this
.
updateTrueCommand
();
...
...
@@ -714,7 +713,6 @@ export class TopbarComponent extends ViewControllerComponent implements OnInit,
return
!
(
actionId
===
'
deregister
'
&&
!
this
.
tcConnected
);
},
saveButtonText
:
this
.
tcConnected
?
helptext
.
updateDialog
.
save_btn
:
helptext
.
updateDialog
.
connect_btn
,
parent
:
this
,
afterInit
:
(
entityDialog
:
EntityDialogComponent
)
=>
{
updateDialog
=
entityDialog
;
// load settings
...
...
@@ -829,7 +827,6 @@ export class TopbarComponent extends ViewControllerComponent implements OnInit,
],
saveButtonText
:
this
.
translate
.
instant
(
'
Save
'
),
custActions
:
[],
parent
:
this
,
customSubmit
:
(
entityDialog
:
EntityDialogComponent
)
=>
{
this
.
loader
.
open
();
const
pwChange
=
entityDialog
.
formValue
;
...
...
This diff is collapsed.
Click to expand it.
src/app/enums/fibre-channel-port-mode.enum.ts
0 → 100644
View file @
9ac541d7
export
enum
FibreChannelPortMode
{
Initiator
=
'
INITIATOR
'
,
Target
=
'
TARGET
'
,
Disabled
=
'
DISABLED
'
,
}
This diff is collapsed.
Click to expand it.
src/app/interfaces/api-directory.interface.ts
View file @
9ac541d7
...
...
@@ -63,7 +63,7 @@ import {
CloudsyncBucket
,
CloudsyncCredential
,
CloudsyncCredentialUpdate
,
CloudsyncCredentialVerify
,
CloudsyncOneDriveDrive
,
CloudsyncOneDriveParams
,
CloudsyncCredentialVerify
,
CloudsyncCredentialVerifyResult
,
CloudsyncOneDriveDrive
,
CloudsyncOneDriveParams
,
}
from
'
app/interfaces/cloudsync-credential.interface
'
;
import
{
CloudsyncProvider
,
CloudsyncRestoreParams
}
from
'
app/interfaces/cloudsync-provider.interface
'
;
import
{
ConfigResetParams
}
from
'
app/interfaces/config-reset-params.interface
'
;
...
...
@@ -98,7 +98,7 @@ import { DsUncachedGroup, DsUncachedUser } from 'app/interfaces/ds-cache.interfa
import
{
DynamicDnsConfig
,
DynamicDnsUpdate
}
from
'
app/interfaces/dynamic-dns.interface
'
;
import
{
Enclosure
}
from
'
app/interfaces/enclosure.interface
'
;
import
{
FailoverConfig
,
FailoverRemoteCall
,
FailoverUpdate
}
from
'
app/interfaces/failover.interface
'
;
import
{
FibreChannelPort
}
from
'
app/interfaces/fibre-channel-port.interface
'
;
import
{
FibreChannelPort
,
FibreChannelPortUpdate
}
from
'
app/interfaces/fibre-channel-port.interface
'
;
import
{
FileRecord
,
ListdirQueryParams
}
from
'
app/interfaces/file-record.interface
'
;
import
{
FileSystemStat
,
Statfs
}
from
'
app/interfaces/filesystem-stat.interface
'
;
import
{
FtpConfig
,
FtpConfigUpdate
}
from
'
app/interfaces/ftp-config.interface
'
;
...
...
@@ -393,7 +393,7 @@ export type ApiDirectory = {
response
:
CloudsyncCredential
;
};
'
cloudsync.credentials.delete
'
:
{
params
:
[
id
:
number
];
response
:
boolean
};
'
cloudsync.credentials.verify
'
:
{
params
:
[
CloudsyncCredentialVerify
];
response
:
any
};
'
cloudsync.credentials.verify
'
:
{
params
:
[
CloudsyncCredentialVerify
];
response
:
CloudsyncCredentialVerifyResult
};
'
cloudsync.onedrive_list_drives
'
:
{
params
:
[
CloudsyncOneDriveParams
];
response
:
CloudsyncOneDriveDrive
[]
};
'
cloudsync.list_buckets
'
:
{
params
:
[
id
:
number
];
response
:
CloudsyncBucket
[]
};
'
cloudsync.list_directory
'
:
{
params
:
[
CloudSyncListDirectoryParams
];
response
:
CloudSyncDirectoryListing
[]
};
...
...
@@ -425,7 +425,6 @@ export type ApiDirectory = {
'
disk.query
'
:
{
params
:
QueryParams
<
Disk
,
DiskQueryOptions
>
;
response
:
Disk
[]
};
'
disk.update
'
:
{
params
:
[
string
,
DiskUpdate
];
response
:
Disk
};
'
disk.get_unused
'
:
{
params
:
[
joinPartitions
?:
boolean
];
response
:
UnusedDisk
[]
};
'
disk.get_encrypted
'
:
{
params
:
any
;
response
:
any
};
'
disk.temperatures
'
:
{
params
:
[
disks
:
string
[]];
response
:
DiskTemperatures
};
'
disk.wipe
'
:
{
params
:
DiskWipeParams
;
response
:
void
};
...
...
@@ -436,7 +435,7 @@ export type ApiDirectory = {
// Enclosure
'
enclosure.query
'
:
{
params
:
void
;
response
:
Enclosure
[]
};
'
enclosure.update
'
:
{
params
:
[
enclosureId
:
string
,
update
:
{
label
:
string
}];
response
:
Enclosure
};
'
enclosure.set_slot_status
'
:
{
params
:
[
id
:
string
,
slot
:
number
,
status
:
EnclosureSlotStatus
];
response
:
any
};
'
enclosure.set_slot_status
'
:
{
params
:
[
id
:
string
,
slot
:
number
,
status
:
EnclosureSlotStatus
];
response
:
void
};
// Filesystem
'
filesystem.acl_is_trivial
'
:
{
...
...
@@ -473,7 +472,7 @@ export type ApiDirectory = {
// FCPort
'
fcport.query
'
:
{
params
:
QueryParams
<
FibreChannelPort
>
;
response
:
FibreChannelPort
[]
};
'
fcport.update
'
:
{
params
:
any
;
response
:
any
};
'
fcport.update
'
:
{
params
:
[
id
:
string
,
update
:
FibreChannelPortUpdate
]
;
response
:
unknown
};
// DS Cache
'
dscache.get_uncached_group
'
:
{
params
:
[
groupname
:
string
];
response
:
DsUncachedGroup
};
...
...
@@ -640,11 +639,11 @@ export type ApiDirectory = {
'
openvpn.server.config
'
:
{
params
:
void
;
response
:
OpenvpnServerConfig
};
// Pool
'
pool.attach
'
:
{
params
:
[
id
:
number
,
params
:
PoolAttachParams
];
response
:
any
};
'
pool.attach
'
:
{
params
:
[
id
:
number
,
params
:
PoolAttachParams
];
response
:
void
};
'
pool.attachments
'
:
{
params
:
[
id
:
number
];
response
:
PoolAttachment
[]
};
'
pool.create
'
:
{
params
:
[
CreatePool
];
response
:
Pool
};
'
pool.dataset.attachments
'
:
{
params
:
[
datasetId
:
string
];
response
:
PoolAttachment
[]
};
'
pool.dataset.change_key
'
:
{
params
:
[
id
:
number
,
params
:
DatasetChangeKeyParams
];
response
:
any
};
'
pool.dataset.change_key
'
:
{
params
:
[
id
:
number
,
params
:
DatasetChangeKeyParams
];
response
:
void
};
'
pool.dataset.compression_choices
'
:
{
params
:
void
;
response
:
Choices
};
'
pool.dataset.create
'
:
{
params
:
any
;
response
:
Dataset
};
'
pool.dataset.delete
'
:
{
params
:
[
path
:
string
,
params
:
{
recursive
:
boolean
;
force
?:
boolean
}];
response
:
boolean
};
...
...
@@ -669,7 +668,7 @@ export type ApiDirectory = {
'
pool.dataset.unlock_services_restart_choices
'
:
{
params
:
[
id
:
string
];
response
:
Choices
};
'
pool.dataset.update
'
:
{
params
:
any
;
response
:
Dataset
};
'
pool.detach
'
:
{
params
:
[
id
:
number
,
params
:
{
label
:
string
}];
response
:
boolean
};
'
pool.download_encryption_key
'
:
{
params
:
any
;
response
:
any
};
'
pool.download_encryption_key
'
:
{
params
:
any
;
response
:
string
};
'
pool.expand
'
:
{
params
:
PoolExpandParams
;
response
:
null
};
'
pool.export
'
:
{
params
:
PoolExportParams
;
response
:
void
};
'
pool.filesystem_choices
'
:
{
params
:
[
DatasetType
[]?];
response
:
string
[]
};
...
...
@@ -680,7 +679,6 @@ export type ApiDirectory = {
'
pool.import_find
'
:
{
params
:
void
;
response
:
PoolFindResult
[]
};
'
pool.import_pool
'
:
{
params
:
[
PoolImportParams
];
response
:
boolean
};
'
pool.is_upgraded
'
:
{
params
:
[
poolId
:
number
];
response
:
boolean
};
'
pool.lock
'
:
{
params
:
any
;
response
:
any
};
'
pool.offline
'
:
{
params
:
[
id
:
number
,
params
:
{
label
:
string
}];
response
:
boolean
};
'
pool.online
'
:
{
params
:
[
id
:
number
,
params
:
{
label
:
string
}];
response
:
boolean
};
'
pool.passphrase
'
:
{
params
:
any
;
response
:
any
};
...
...
@@ -688,7 +686,7 @@ export type ApiDirectory = {
'
pool.query
'
:
{
params
:
QueryParams
<
Pool
>
;
response
:
Pool
[]
};
'
pool.recoverykey_rm
'
:
{
params
:
any
;
response
:
any
};
'
pool.rekey
'
:
{
params
:
any
;
response
:
any
};
'
pool.remove
'
:
{
params
:
PoolRemoveParams
;
response
:
any
};
'
pool.remove
'
:
{
params
:
PoolRemoveParams
;
response
:
void
};
'
pool.replace
'
:
{
params
:
[
id
:
number
,
params
:
PoolReplaceParams
];
response
:
boolean
};
'
pool.resilver.config
'
:
{
params
:
void
;
response
:
ResilverConfig
};
'
pool.resilver.update
'
:
{
params
:
[
ResilverConfigUpdate
];
response
:
ResilverConfig
};
...
...
@@ -711,7 +709,7 @@ export type ApiDirectory = {
'
replication.create
'
:
{
params
:
any
;
response
:
any
};
'
replication.query
'
:
{
params
:
QueryParams
<
ReplicationTask
>
;
response
:
ReplicationTask
[]
};
'
replication.restore
'
:
{
params
:
[
id
:
number
,
params
:
{
name
:
string
;
target_dataset
:
string
}];
response
:
void
};
'
replication.run
'
:
{
params
:
[
id
:
number
];
response
:
any
};
'
replication.run
'
:
{
params
:
[
id
:
number
];
response
:
number
};
'
replication.delete
'
:
{
params
:
[
id
:
number
];
response
:
boolean
};
'
replication.count_eligible_manual_snapshots
'
:
{
params
:
[
CountManualSnapshotsParams
];
response
:
EligibleManualSnapshotsCount
};
'
replication.list_naming_schemas
'
:
{
params
:
void
;
response
:
string
[]
};
...
...
@@ -889,7 +887,7 @@ export type ApiDirectory = {
'
vm.device.delete
'
:
{
params
:
[
id
:
number
];
response
:
boolean
};
'
vm.random_mac
'
:
{
params
:
void
;
response
:
string
};
'
vm.device.query
'
:
{
params
:
QueryParams
<
VmDevice
>
;
response
:
VmDevice
[]
};
'
vm.stop
'
:
{
params
:
VmStopParams
;
response
:
any
};
'
vm.stop
'
:
{
params
:
VmStopParams
;
response
:
void
};
'
vm.maximum_supported_vcpus
'
:
{
params
:
void
;
response
:
number
};
'
vm.device.update
'
:
{
params
:
[
id
:
number
,
update
:
VmDeviceUpdate
];
response
:
VmDevice
};
'
vm.port_wizard
'
:
{
params
:
void
;
response
:
VmPortWizardResult
};
...
...
@@ -915,7 +913,7 @@ export type ApiDirectory = {
// User
'
user.update
'
:
{
params
:
[
id
:
number
,
update
:
UserUpdate
];
response
:
number
};
'
user.create
'
:
{
params
:
any
;
response
:
any
};
'
user.create
'
:
{
params
:
[
UserUpdate
]
;
response
:
number
};
'
user.query
'
:
{
params
:
QueryParams
<
User
>
;
response
:
User
[]
};
'
user.set_root_password
'
:
{
params
:
[
password
:
string
];
response
:
void
};
'
user.delete
'
:
{
params
:
DeleteUserParams
;
response
:
number
};
...
...
@@ -938,7 +936,7 @@ export type ApiDirectory = {
'
update.get_pending
'
:
{
params
:
void
;
response
:
SystemUpdateChange
[]
};
'
update.check_available
'
:
{
params
:
void
;
response
:
SystemUpdate
};
'
update.set_train
'
:
{
params
:
[
train
:
string
];
response
:
void
};
'
update.download
'
:
{
params
:
any
;
response
:
an
y
};
'
update.download
'
:
{
params
:
void
;
response
:
boole
an
};
'
update.update
'
:
{
params
:
[
UpdateParams
];
response
:
void
};
// ZFS
...
...
This diff is collapsed.
Click to expand it.
src/app/interfaces/cloudsync-credential.interface.ts
View file @
9ac541d7
...
...
@@ -11,6 +11,12 @@ export type CloudsyncCredentialUpdate = Omit<CloudsyncCredential, 'id'>;
export
type
CloudsyncCredentialVerify
=
Pick
<
CloudsyncCredential
,
'
provider
'
|
'
attributes
'
>
;
export
interface
CloudsyncCredentialVerifyResult
{
error
?:
string
;
excerpt
?:
string
;
valid
:
boolean
;
}
export
interface
CloudsyncBucket
{
Name
:
string
;
Path
:
string
;
...
...
This diff is collapsed.
Click to expand it.
src/app/interfaces/fibre-channel-port.interface.ts
View file @
9ac541d7
import
{
FibreChannelPortMode
}
from
'
app/enums/fibre-channel-port-mode.enum
'
;
export
interface
FibreChannelPort
{
name
:
string
;
wwpn
:
unknown
;
state
:
string
;
}
export
interface
FibreChannelPortUpdate
{
mode
:
FibreChannelPortMode
;
target
:
number
;
initiators
:
string
;
}
This diff is collapsed.
Click to expand it.
src/app/pages/api-keys/api-keys.component.ts
View file @
9ac541d7
...
...
@@ -71,7 +71,6 @@ export class ApiKeysComponent implements EntityTableConfig {
entityFrom
.
formGroup
.
controls
[
'
name
'
].
setValue
(
this
.
currItem
.
name
);
}
},
parent
:
this
,
};
timeZone
:
string
;
...
...
@@ -114,7 +113,7 @@ export class ApiKeysComponent implements EntityTableConfig {
this
.
dialogService
.
dialogForm
(
this
.
apikeysFormConf
);
}
doSubmit
(
entityDialogForm
:
EntityDialogComponent
<
ApiKeysComponent
>
):
void
{
doSubmit
(
entityDialogForm
:
EntityDialogComponent
):
void
{
if
(
this
.
currItem
)
{
this
.
ws
.
call
(
this
.
editCall
,
[
this
.
currItem
.
id
,
entityDialogForm
.
formValue
]).
pipe
(
untilDestroyed
(
this
)).
subscribe
(
(
res
)
=>
{
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/applications/catalog/catalog.component.ts
View file @
9ac541d7
...
...
@@ -87,7 +87,6 @@ export class CatalogComponent implements OnInit {
method_ws
:
'
kubernetes.update
'
,
saveButtonText
:
helptext
.
choosePool
.
action
,
customSubmit
:
(
entityForm
)
=>
this
.
doPoolSelect
(
entityForm
),
parent
:
this
,
};
constructor
(
...
...
@@ -318,7 +317,7 @@ export class CatalogComponent implements OnInit {
});
}
doPoolSelect
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doPoolSelect
(
entityDialog
:
EntityDialogComponent
):
void
{
const
pool
=
entityDialog
.
formGroup
.
controls
[
'
pools
'
].
value
;
const
migrateApplications
=
entityDialog
.
formGroup
.
controls
[
'
migrateApplications
'
].
value
;
this
.
dialogService
.
closeAllDialogs
();
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/applications/chart-releases/chart-releases.component.ts
View file @
9ac541d7
...
...
@@ -89,7 +89,6 @@ export class ChartReleasesComponent implements OnInit {
method_ws
:
'
chart.release.rollback
'
,
saveButtonText
:
helptext
.
charts
.
rollback_dialog
.
action
,
customSubmit
:
(
entityDialog
)
=>
this
.
doRollback
(
entityDialog
),
parent
:
this
,
};
choosePod
:
DialogFormConfiguration
=
{
...
...
@@ -113,7 +112,6 @@ export class ChartReleasesComponent implements OnInit {
saveButtonText
:
helptext
.
podConsole
.
choosePod
.
action
,
customSubmit
:
(
entityDialog
)
=>
this
.
doPodSelect
(
entityDialog
),
afterInit
:
(
entityDialog
)
=>
this
.
afterShellDialogInit
(
entityDialog
),
parent
:
this
,
};
choosePodForLogs
:
DialogFormConfiguration
=
{
...
...
@@ -138,7 +136,6 @@ export class ChartReleasesComponent implements OnInit {
saveButtonText
:
helptext
.
podConsole
.
choosePod
.
action
,
customSubmit
:
(
entityDialog
)
=>
this
.
doPodSelectForLogs
(
entityDialog
),
afterInit
:
(
entityDialog
)
=>
this
.
afterLogsDialogInit
(
entityDialog
),
parent
:
this
,
};
readonly
ChartReleaseStatus
=
ChartReleaseStatus
;
...
...
@@ -334,7 +331,7 @@ export class ChartReleasesComponent implements OnInit {
this
.
dialogService
.
dialogForm
(
this
.
rollBackChart
,
true
);
}
doRollback
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doRollback
(
entityDialog
:
EntityDialogComponent
):
void
{
const
form
=
entityDialog
.
formGroup
.
controls
;
const
payload
=
{
item_version
:
form
[
'
item_version
'
].
value
,
...
...
@@ -575,14 +572,14 @@ export class ChartReleasesComponent implements OnInit {
});
}
doPodSelect
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doPodSelect
(
entityDialog
:
EntityDialogComponent
):
void
{
const
pod
=
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
value
;
const
command
=
entityDialog
.
formGroup
.
controls
[
'
command
'
].
value
;
this
.
router
.
navigate
(
new
Array
(
'
/apps/1/shell/
'
).
concat
([
this
.
selectedAppName
,
pod
,
command
]));
this
.
dialogService
.
closeAllDialogs
();
}
doPodSelectForLogs
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doPodSelectForLogs
(
entityDialog
:
EntityDialogComponent
):
void
{
const
pod
=
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
value
;
const
container
=
entityDialog
.
formGroup
.
controls
[
'
containers
'
].
value
;
const
tailLines
=
entityDialog
.
formGroup
.
controls
[
'
tail_lines
'
].
value
;
...
...
@@ -590,7 +587,7 @@ export class ChartReleasesComponent implements OnInit {
this
.
dialogService
.
closeAllDialogs
();
}
afterShellDialogInit
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
afterShellDialogInit
(
entityDialog
:
EntityDialogComponent
):
void
{
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
valueChanges
.
pipe
(
untilDestroyed
(
this
)).
subscribe
((
value
)
=>
{
const
containers
=
this
.
podDetails
[
value
];
const
containerFc
=
_
.
find
(
entityDialog
.
fieldConfig
,
{
name
:
'
containers
'
})
as
FormSelectConfig
;
...
...
@@ -603,7 +600,7 @@ export class ChartReleasesComponent implements OnInit {
});
}
afterLogsDialogInit
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
afterLogsDialogInit
(
entityDialog
:
EntityDialogComponent
):
void
{
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
valueChanges
.
pipe
(
untilDestroyed
(
this
)).
subscribe
((
value
)
=>
{
const
containers
=
this
.
podDetails
[
value
];
const
containerFc
=
_
.
find
(
entityDialog
.
fieldConfig
,
{
name
:
'
containers
'
})
as
FormSelectConfig
;
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/applications/docker-images/docker-images.component.ts
View file @
9ac541d7
...
...
@@ -64,7 +64,6 @@ export class DockerImagesComponent implements EntityTableConfig {
}],
saveButtonText
:
helptext
.
dockerImages
.
chooseTag
.
action
,
customSubmit
:
(
entityDialog
)
=>
this
.
updateImage
(
entityDialog
),
parent
:
this
,
};
refresh
():
void
{
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/applications/pod-logs/pod-logs.component.ts
View file @
9ac541d7
...
...
@@ -237,7 +237,6 @@ export class PodLogsComponent implements OnInit, OnDestroy {
}
},
afterInit
:
(
entityDialog
)
=>
this
.
afterLogsDialogInit
(
entityDialog
),
parent
:
this
,
};
}
...
...
@@ -248,7 +247,7 @@ export class PodLogsComponent implements OnInit, OnDestroy {
}
// download log
download
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
download
(
entityDialog
:
EntityDialogComponent
):
void
{
const
chartReleaseName
=
entityDialog
.
formGroup
.
controls
[
'
apps
'
].
value
;
const
podName
=
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
value
;
const
containerName
=
entityDialog
.
formGroup
.
controls
[
'
containers
'
].
value
;
...
...
@@ -282,7 +281,7 @@ export class PodLogsComponent implements OnInit, OnDestroy {
});
}
onChooseLogs
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
onChooseLogs
(
entityDialog
:
EntityDialogComponent
):
void
{
this
.
chart_release_name
=
entityDialog
.
formGroup
.
controls
[
'
apps
'
].
value
;
this
.
pod_name
=
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
value
;
this
.
container_name
=
entityDialog
.
formGroup
.
controls
[
'
containers
'
].
value
;
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/applications/pod-shell/pod-shell.component.ts
View file @
9ac541d7
...
...
@@ -112,11 +112,10 @@ export class PodShellComponent implements TerminalConfiguration {
saveButtonText
:
helptext
.
podConsole
.
choosePod
.
action
,
customSubmit
:
(
entityDialog
)
=>
this
.
onChooseShell
(
entityDialog
),
afterInit
:
(
entityDialog
)
=>
this
.
afterShellDialogInit
(
entityDialog
),
parent
:
this
,
};
}
onChooseShell
(
entityDialog
:
EntityDialogComponent
<
PodShellComponent
>
):
void
{
onChooseShell
(
entityDialog
:
EntityDialogComponent
):
void
{
this
.
podName
=
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
value
;
this
.
containerName
=
entityDialog
.
formGroup
.
controls
[
'
containers
'
].
value
;
this
.
command
=
entityDialog
.
formGroup
.
controls
[
'
command
'
].
value
;
...
...
@@ -125,7 +124,7 @@ export class PodShellComponent implements TerminalConfiguration {
this
.
dialogService
.
closeAllDialogs
();
}
afterShellDialogInit
(
entityDialog
:
EntityDialogComponent
<
PodShellComponent
>
):
void
{
afterShellDialogInit
(
entityDialog
:
EntityDialogComponent
):
void
{
entityDialog
.
formGroup
.
controls
[
'
pods
'
].
valueChanges
.
pipe
(
untilDestroyed
(
this
)).
subscribe
((
value
)
=>
{
const
containers
=
this
.
podDetails
[
value
];
const
containerFc
=
_
.
find
(
entityDialog
.
fieldConfig
,
{
name
:
'
containers
'
})
as
FormSelectConfig
;
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/common/entity/entity-dialog/dialog-form-configuration.interface.ts
View file @
9ac541d7
...
...
@@ -2,25 +2,21 @@ import { ApiMethod } from 'app/interfaces/api-directory.interface';
import
{
EntityDialogComponent
}
from
'
app/pages/common/entity/entity-dialog/entity-dialog.component
'
;
import
{
FieldConfig
}
from
'
../entity-form/models/field-config.interface
'
;
export
interface
DialogFormConfiguration
<
P
=
any
>
{
export
interface
DialogFormConfiguration
{
title
:
string
;
fieldConfig
:
FieldConfig
<
P
>
[];
fieldConfig
:
FieldConfig
[];
method_rest
?:
string
;
method_ws
?:
ApiMethod
;
saveButtonText
?:
string
;
cancelButtonText
?:
string
;
custActions
?:
DialogFormCustomAction
[];
customSubmit
?:
(
entityDialog
:
EntityDialogComponent
<
P
>
)
=>
void
;
customSubmit
?:
(
entityDialog
:
EntityDialogComponent
)
=>
void
;
isCustActionVisible
?:
(
actionId
:
string
)
=>
boolean
;
hideButton
?:
boolean
;
message
?:
string
;
warning
?:
string
;
preInit
?:
(
entityDialog
:
EntityDialogComponent
<
P
>
)
=>
void
;
afterInit
?:
(
entityDialog
:
EntityDialogComponent
<
P
>
)
=>
void
;
/**
* @deprecated Capture parent with an arrow function instead
*/
parent
?:
P
;
preInit
?:
(
entityDialog
:
EntityDialogComponent
)
=>
void
;
afterInit
?:
(
entityDialog
:
EntityDialogComponent
)
=>
void
;
confirmCheckbox
?:
boolean
;
hideCancel
?:
boolean
;
confirmInstructions
?:
boolean
;
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/common/entity/entity-dialog/entity-dialog.component.ts
View file @
9ac541d7
...
...
@@ -21,8 +21,8 @@ import { DialogFormConfiguration } from './dialog-form-configuration.interface';
styleUrls
:
[
'
./entity-dialog.component.scss
'
],
providers
:
[
EntityFormService
,
DatePipe
,
FieldRelationService
],
})
export
class
EntityDialogComponent
<
P
=
any
>
implements
OnInit
{
@
Input
()
conf
:
DialogFormConfiguration
<
P
>
;
export
class
EntityDialogComponent
implements
OnInit
{
@
Input
()
conf
:
DialogFormConfiguration
;
title
:
string
;
warning
:
string
;
...
...
@@ -33,10 +33,6 @@ export class EntityDialogComponent<P = any> implements OnInit {
error
:
string
;
formValue
:
any
;
showPassword
=
false
;
/**
* @deprecated Capture parent with an arrow function instead
*/
parent
:
P
;
submitEnabled
=
true
;
instructions
:
string
;
confirmCheckbox
=
false
;
...
...
@@ -57,10 +53,6 @@ export class EntityDialogComponent<P = any> implements OnInit {
this
.
fieldConfig
=
this
.
conf
.
fieldConfig
;
if
(
this
.
conf
.
parent
)
{
this
.
parent
=
this
.
conf
.
parent
;
}
if
(
this
.
conf
.
confirmCheckbox
)
{
this
.
confirmCheckbox
=
this
.
conf
.
confirmCheckbox
;
this
.
submitEnabled
=
false
;
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/common/entity/utils.ts
View file @
9ac541d7
...
...
@@ -22,6 +22,19 @@ import { Relation, RelationGroup } from './entity-form/models/field-relation.int
// eslint-disable-next-line @typescript-eslint/naming-convention
export
const
NULL_VALUE
=
'
null_value
'
;
// eslint-disable-next-line @typescript-eslint/ban-types
export
type
ItemBeforeFlattening
=
object
&
{
id
:
string
|
number
;
children
?:
ItemBeforeFlattening
[];
};
type
DataBeforeFlattening
=
ItemBeforeFlattening
|
ItemBeforeFlattening
[];
export
interface
FlattenedData
extends
Record
<
string
,
unknown
>
{
_level
?:
number
;
_parent
?:
string
|
number
;
}
export
class
EntityUtils
{
handleError
(
entity
:
any
,
res
:
any
):
void
{
if
(
res
.
code
===
409
)
{
...
...
@@ -161,15 +174,15 @@ export class EntityUtils {
return
(
!!
a
)
&&
(
a
.
constructor
===
Object
);
};
flattenData
(
data
:
any
|
any
[]
,
level
=
0
,
parent
?:
any
):
any
[]
{
let
ndata
:
any
[]
=
[];
flattenData
(
data
:
DataBeforeFlattening
,
level
=
0
,
parent
?:
{
id
:
string
|
number
}):
FlattenedData
[]
{
let
ndata
:
FlattenedData
[]
=
[];
if
(
this
.
isObject
(
data
))
{
data
=
[
data
];
}
(
data
as
any
[])
.
forEach
((
item
)
=>
{
item
.
_level
=
level
;
data
.
forEach
((
item
)
=>
{
(
item
as
FlattenedData
)
.
_level
=
level
;
if
(
parent
)
{
item
.
_parent
=
parent
.
id
;
(
item
as
FlattenedData
)
.
_parent
=
parent
.
id
;
}
ndata
.
push
(
item
);
if
(
item
.
children
)
{
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/credentials/backup-credentials/forms/cloud-credentials-form.component.ts
View file @
9ac541d7
...
...
@@ -7,7 +7,11 @@ import * as _ from 'lodash';
import
{
take
}
from
'
rxjs/operators
'
;
import
{
KeychainCredentialType
}
from
'
app/enums/keychain-credential-type.enum
'
;
import
{
helptextSystemCloudcredentials
as
helptext
}
from
'
app/helptext/system/cloud-credentials
'
;
import
{
CloudsyncCredential
}
from
'
app/interfaces/cloudsync-credential.interface
'
;
import
{
CloudsyncCredential
,
CloudsyncCredentialVerify
,
CloudsyncOneDriveDrive
,
}
from
'
app/interfaces/cloudsync-credential.interface
'
;
import
{
CloudsyncProvider
}
from
'
app/interfaces/cloudsync-provider.interface
'
;
import
{
FormConfiguration
}
from
'
app/interfaces/entity-form.interface
'
;
import
{
OauthMessage
}
from
'
app/interfaces/oauth-message.interface
'
;
...
...
@@ -1390,7 +1394,7 @@ export class CloudCredentialsFormComponent implements FormConfiguration {
const
driveTypeCtrl
=
entityForm
.
formGroup
.
controls
[
'
drive_type-ONEDRIVE
'
];
const
driveIdCtrl
=
entityForm
.
formGroup
.
controls
[
'
drive_id-ONEDRIVE
'
];
entityForm
.
formGroup
.
controls
[
'
drives-ONEDRIVE
'
].
valueChanges
.
pipe
(
untilDestroyed
(
this
)).
subscribe
((
res
:
any
)
=>
{
entityForm
.
formGroup
.
controls
[
'
drives-ONEDRIVE
'
].
valueChanges
.
pipe
(
untilDestroyed
(
this
)).
subscribe
((
res
:
CloudsyncOneDriveDrive
)
=>
{
if
(
res
)
{
driveTypeCtrl
.
setValue
(
res
.
drive_type
);
driveIdCtrl
.
setValue
(
res
.
drive_id
);
...
...
@@ -1432,7 +1436,7 @@ export class CloudCredentialsFormComponent implements FormConfiguration {
);
}
verifyCredentials
(
value
:
any
):
void
{
verifyCredentials
(
value
:
CloudsyncCredentialVerify
&
{
name
:
string
}
):
void
{
delete
value
[
'
name
'
];
this
.
ws
.
call
(
'
cloudsync.credentials.verify
'
,
[
value
]).
pipe
(
untilDestroyed
(
this
)).
subscribe
(
(
res
)
=>
{
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/credentials/certificates-dash/certificates-dash.component.ts
View file @
9ac541d7
...
...
@@ -115,11 +115,11 @@ export class CertificatesDashComponent implements OnInit {
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateAddComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateAddComponent
);
},
edit
(
row
:
Certificate
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateEditComponent
,
row
.
id
);
edit
:
(
row
:
Certificate
)
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateEditComponent
,
row
.
id
);
},
},
},
...
...
@@ -142,11 +142,11 @@ export class CertificatesDashComponent implements OnInit {
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateAddComponent
,
'
csr
'
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateAddComponent
,
'
csr
'
);
},
edit
(
row
:
Certificate
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateEditComponent
,
row
.
id
);
edit
:
(
row
:
Certificate
)
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateEditComponent
,
row
.
id
);
},
},
},
...
...
@@ -182,15 +182,15 @@ export class CertificatesDashComponent implements OnInit {
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateAuthorityAddComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateAuthorityAddComponent
);
},
edit
(
row
:
CertificateAuthority
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
CertificateAuthorityEditComponent
,
row
.
id
);
edit
:
(
row
:
CertificateAuthority
)
=>
{
this
.
modalService
.
openInSlideIn
(
CertificateAuthorityEditComponent
,
row
.
id
);
},
delete
(
row
:
CertificateAuthority
,
table
:
TableComponent
)
{
delete
:
(
row
:
CertificateAuthority
,
table
:
TableComponent
)
=>
{
if
(
row
.
signed_certificates
>
0
)
{
this
.
parent
.
dialogService
.
confirm
({
this
.
dialogService
.
confirm
({
title
:
helptextSystemCa
.
delete_error
.
title
,
message
:
helptextSystemCa
.
delete_error
.
message
,
hideCheckBox
:
true
,
...
...
@@ -198,7 +198,7 @@ export class CertificatesDashComponent implements OnInit {
hideCancel
:
true
,
});
}
else
{
this
.
parent
.
tableService
.
delete
(
table
,
row
);
this
.
tableService
.
delete
(
table
,
row
);
}
},
},
...
...
@@ -215,11 +215,11 @@ export class CertificatesDashComponent implements OnInit {
{
name
:
this
.
translate
.
instant
(
'
Authenticator
'
),
prop
:
'
authenticator
'
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
AcmednsFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
AcmednsFormComponent
);
},
edit
(
row
:
CertificateAuthority
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
AcmednsFormComponent
,
row
.
id
);
edit
:
(
row
:
CertificateAuthority
)
=>
{
this
.
modalService
.
openInSlideIn
(
AcmednsFormComponent
,
row
.
id
);
},
},
},
...
...
@@ -412,10 +412,9 @@ export class CertificatesDashComponent implements OnInit {
method_ws
:
'
certificateauthority.ca_sign_csr
'
,
saveButtonText
:
helptextSystemCa
.
sign
.
sign
,
customSubmit
:
(
entityDialog
)
=>
this
.
doSignCsr
(
entityDialog
),
parent
:
this
,
};
doSignCsr
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doSignCsr
(
entityDialog
:
EntityDialogComponent
):
void
{
const
payload
=
{
ca_id
:
this
.
caId
,
csr_cert_id
:
entityDialog
.
formGroup
.
controls
.
csr_cert_id
.
value
,
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/credentials/certificates-dash/forms/acmedns-form.component.ts
View file @
9ac541d7
...
...
@@ -55,8 +55,7 @@ export class AcmednsFormComponent implements FormConfiguration {
name
:
'
authenticator
'
,
placeholder
:
helptext
.
authenticator_provider_placeholder
,
tooltip
:
helptext
.
authenticator_provider_tooltip
,
options
:
[
],
options
:
[],
parent
:
this
,
};
const
fieldSet
:
FieldSet
[]
=
[
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/credentials/certificates-dash/forms/ca-edit.component.ts
View file @
9ac541d7
...
...
@@ -237,7 +237,6 @@ export class CertificateAuthorityEditComponent implements FormConfiguration {
method_ws
:
'
certificateauthority.ca_sign_csr
'
,
saveButtonText
:
helptextSystemCa
.
sign
.
sign
,
customSubmit
:
(
entityDialog
)
=>
this
.
doSignCsr
(
entityDialog
),
parent
:
this
,
};
custActions
=
[
...
...
@@ -286,7 +285,7 @@ export class CertificateAuthorityEditComponent implements FormConfiguration {
this
.
title
=
helptextSystemCa
.
edit
.
title
;
}
doSignCsr
(
entityDialog
:
EntityDialogComponent
<
this
>
):
void
{
doSignCsr
(
entityDialog
:
EntityDialogComponent
):
void
{
const
payload
=
{
ca_id
:
this
.
rowNum
,
csr_cert_id
:
entityDialog
.
formGroup
.
controls
.
csr_cert_id
.
value
,
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/data-protection/components/data-protection-dashboard/data-protection-dashboard.component.ts
View file @
9ac541d7
...
...
@@ -153,11 +153,11 @@ export class DataProtectionDashboardComponent implements OnInit {
key_props
:
[
'
pool_name
'
],
},
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
ScrubFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
ScrubFormComponent
);
},
edit
(
row
:
ScrubTaskUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
ScrubFormComponent
,
row
.
id
);
edit
:
(
row
:
ScrubTaskUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
ScrubFormComponent
,
row
.
id
);
},
tableActions
:
[
{
...
...
@@ -202,14 +202,14 @@ export class DataProtectionDashboardComponent implements OnInit {
dataSourceHelper
:
this
.
snapshotDataSourceHelper
,
isActionVisible
:
this
.
isActionVisible
,
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
SnapshotFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
SnapshotFormComponent
);
},
edit
(
row
:
PeriodicSnapshotTaskUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
SnapshotFormComponent
,
row
.
id
);
edit
:
(
row
:
PeriodicSnapshotTaskUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
SnapshotFormComponent
,
row
.
id
);
},
onButtonClick
(
row
)
{
this
.
parent
.
stateButton
(
row
);
onButtonClick
:
(
row
)
=>
{
this
.
stateButton
(
row
);
},
},
},
...
...
@@ -245,14 +245,14 @@ export class DataProtectionDashboardComponent implements OnInit {
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
ReplicationWizardComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
ReplicationWizardComponent
);
},
edit
(
row
:
ReplicationTaskUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
ReplicationFormComponent
,
row
.
id
);
edit
:
(
row
:
ReplicationTaskUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
ReplicationFormComponent
,
row
.
id
);
},
onButtonClick
(
row
)
{
this
.
parent
.
stateButton
(
row
);
onButtonClick
:
(
row
)
=>
{
this
.
stateButton
(
row
);
},
},
},
...
...
@@ -293,14 +293,14 @@ export class DataProtectionDashboardComponent implements OnInit {
},
],
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
CloudsyncFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
CloudsyncFormComponent
);
},
edit
(
row
:
CloudSyncTaskUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
CloudsyncFormComponent
,
row
.
id
);
edit
:
(
row
:
CloudSyncTaskUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
CloudsyncFormComponent
,
row
.
id
);
},
onButtonClick
(
row
:
CloudSyncTaskUi
)
{
this
.
parent
.
stateButton
(
row
);
onButtonClick
:
(
row
:
CloudSyncTaskUi
)
=>
{
this
.
stateButton
(
row
);
},
},
},
...
...
@@ -338,14 +338,14 @@ export class DataProtectionDashboardComponent implements OnInit {
getActions
:
this
.
getRsyncActions
.
bind
(
this
),
isActionVisible
:
this
.
isActionVisible
,
parent
:
this
,
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
RsyncFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
RsyncFormComponent
);
},
edit
(
row
:
RsyncTaskUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
RsyncFormComponent
,
row
.
id
);
edit
:
(
row
:
RsyncTaskUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
RsyncFormComponent
,
row
.
id
);
},
onButtonClick
(
row
:
RsyncTaskUi
)
{
this
.
parent
.
stateButton
(
row
);
onButtonClick
:
(
row
:
RsyncTaskUi
)
=>
{
this
.
stateButton
(
row
);
},
},
},
...
...
@@ -382,11 +382,11 @@ export class DataProtectionDashboardComponent implements OnInit {
prop
:
'
next_run
'
,
},
],
add
()
{
this
.
parent
.
modalService
.
openInSlideIn
(
SmartFormComponent
);
add
:
()
=>
{
this
.
modalService
.
openInSlideIn
(
SmartFormComponent
);
},
edit
(
row
:
SmartTestUi
)
{
this
.
parent
.
modalService
.
openInSlideIn
(
SmartFormComponent
,
row
.
id
);
edit
:
(
row
:
SmartTestUi
)
=>
{
this
.
modalService
.
openInSlideIn
(
SmartFormComponent
,
row
.
id
);
},
},
},
...
...
This diff is collapsed.
Click to expand it.
src/app/pages/network/forms/interfaces-form.component.ts
View file @
9ac541d7
...
...
@@ -573,8 +573,7 @@ export class InterfacesFormComponent extends ViewControllerComponent implements
const
failoverAliases
:
{
address
:
string
}[]
=
[];
const
failoverVirtualAliases
:
{
address
:
string
}[]
=
[];
data
.
aliases
.
forEach
((
alias
:
any
)
=>
{
if
(
!
alias
[
'
delete
'
]
&&
!!
alias
[
'
address
'
])
{
if
(
!
alias
[
'
delete
'
]
&&
!!
alias
[
'
address
'
])
{
const
strings
=
alias
[
'
address
'
].
split
(
'
/
'
);
if
(
strings
[
0
])
{
aliases
.
push
({
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help