Skip to content

Commit

Permalink
Member role management fixes (#695)
Browse files Browse the repository at this point in the history
* Ensure that member roles currently not supported by the dashboard don't get lost when updating a member
Fixed autofocus for some dialogs

* changes as discussed

* revert

* Fix secret access in slots

* Revert "Fix secret access in slots"

This reverts commit 90cc626.

* Fixed secret page, had to move code to parent component due to regression in Vue 2.6
The new v-slot directive, does not provide access to the slotProps to use in an v-if to overwrite the slot conditionally and have the default (fallback) slot content rendered otherwise.
See also these related issues:
vuejs/vue#10784
vuejs/vue#9725
vuejs/vue#9658
  • Loading branch information
grolu committed May 26, 2020
1 parent 1f6fd08 commit ef90078
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 64 deletions.
4 changes: 3 additions & 1 deletion frontend/src/components/NewShoot/NewShootDetails.vue
Expand Up @@ -80,7 +80,7 @@ limitations under the License.
import HintColorizer from '@/components/HintColorizer'
import Purpose from '@/components/Purpose'
import { mapGetters, mapState } from 'vuex'
import { getValidationErrors, compileMarkdown } from '@/utils'
import { getValidationErrors, compileMarkdown, setDelayedInputFocus } from '@/utils'
import { required, maxLength } from 'vuelidate/lib/validators'
import { resourceName, noStartEndHyphen, noConsecutiveHyphen } from '@/utils/validators'
import head from 'lodash/head'
Expand Down Expand Up @@ -251,6 +251,8 @@ export default {
this.userInterActionBus.on('updateK8sMaintenance', updateK8sMaintenance => {
this.updateK8sMaintenance = updateK8sMaintenance
})
setDelayedInputFocus(this, 'name')
}
}
</script>
8 changes: 5 additions & 3 deletions frontend/src/components/ProjectServiceAccountRow.vue
Expand Up @@ -60,9 +60,11 @@ limitations under the License.
</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action class="ml-1">
<v-chip class="mr-3" v-for="roleName in roleDisplayNames" :key="roleName" small color="black" outlined>
{{roleName}}
</v-chip>
<div d-flex flex-row>
<v-chip class="mr-3" v-for="roleName in roleDisplayNames" :key="roleName" small color="black" outlined>
{{roleName}}
</v-chip>
</div>
</v-list-item-action>
<v-list-item-action v-if="isServiceAccountFromCurrentNamespace && canGetSecrets" class="ml-1">
<v-tooltip top>
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/ProjectUserRow.vue
Expand Up @@ -31,9 +31,11 @@ limitations under the License.
</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action class="ml-1">
<v-chip class="mr-3" v-for="roleName in roleDisplayNames" :key="roleName" small color="grey darken-4" outlined>
{{roleName}}
</v-chip>
<div d-flex flex-row>
<v-chip class="mr-3" v-for="roleName in roleDisplayNames" :key="roleName" small color="grey darken-4" outlined>
{{roleName}}
</v-chip>
</div>
</v-list-item-action>
<v-list-item-action v-if="canPatchProject" class="ml-1">
<v-tooltip top>
Expand Down
28 changes: 22 additions & 6 deletions frontend/src/components/Secret.vue
Expand Up @@ -38,16 +38,28 @@ limitations under the License.
<!-- List of the added secrets -->
<v-list two-line v-else>
<secret-row
v-for="row in rows"
:key="row.metadata.name"
:secret="row"
v-for="secret in rows"
:key="secret.metadata.name"
:secret="secret"
:secretDescriptorKey="secretDescriptorKey"
@update="onUpdate"
@delete="onDelete"
>
<!-- forward slot -->
<template v-slot:rowSubTitle>
<slot name="rowSubTitle" :secret="row"></slot>
<template v-if="infrastructureKey === 'openstack' && isOwnSecretBinding(secret)" v-slot:rowSubTitle>
{{secret.data.domainName}} / {{secret.data.tenantName}}
</template>
<template v-else-if="infrastructureKey === 'vsphere' && isOwnSecretBinding(secret)" v-slot:rowSubTitle>
<v-tooltip top>
<template v-slot:activator="{ on }">
<span v-on="on">{{secret.data.vsphereUsername}}</span>
</template>
<span>vSphere Username</span>
</v-tooltip> / <v-tooltip top>
<template v-slot:activator="{ on }">
<span v-on="on">{{secret.data.nsxtUsername}}</span>
</template>
<span>NSX-T Username</span>
</v-tooltip>
</template>
</secret-row>
</v-list>
Expand All @@ -59,6 +71,7 @@ limitations under the License.
import { mapGetters } from 'vuex'
import SecretRow from '@/components/SecretRow'
import InfraIcon from '@/components/VendorIcon'
import { isOwnSecretBinding } from '@/utils'
export default {
components: {
Expand Down Expand Up @@ -128,6 +141,9 @@ export default {
},
onDelete (row) {
this.$emit('delete', row)
},
isOwnSecretBinding (secret) {
return isOwnSecretBinding(secret)
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/ShootDetails/ShootDetailsCard.vue
Expand Up @@ -82,8 +82,9 @@ limitations under the License.
</v-list-item-icon>
<v-list-item-content>
<v-list-item-subtitle>Worker Groups</v-list-item-subtitle>
<v-list-item-title class="d-flex align-center pt-1">
<v-list-item-title class="d-flex flex-wrap align-center pt-1">
<worker-group
class="mr-2 mb-2"
v-for="workerGroup in shootWorkerGroups"
:workerGroup="workerGroup"
:cloudProfileName="shootCloudProfileName"
Expand Down
34 changes: 18 additions & 16 deletions frontend/src/components/dialogs/MemberDialog.vue
Expand Up @@ -42,6 +42,7 @@ limitations under the License.
<v-col cols="4">
<v-select
color="black"
item-color="black"
label="Roles"
:items="roleItems"
multiple
Expand Down Expand Up @@ -80,10 +81,12 @@ import { required } from 'vuelidate/lib/validators'
import { resourceName, unique } from '@/utils/validators'
import GAlert from '@/components/GAlert'
import { errorDetailsFromError, isConflict } from '@/utils/error'
import { serviceAccountToDisplayName, isServiceAccount, setInputFocus, getValidationErrors, MEMBER_ROLE_DESCRIPTORS } from '@/utils'
import { serviceAccountToDisplayName, isServiceAccount, setDelayedInputFocus, getValidationErrors, MEMBER_ROLE_DESCRIPTORS } from '@/utils'
import filter from 'lodash/filter'
import map from 'lodash/map'
import includes from 'lodash/includes'
import forEach from 'lodash/forEach'
import find from 'lodash/find'
const defaultUsername = ''
const defaultServiceName = 'robot'
Expand Down Expand Up @@ -117,6 +120,7 @@ export default {
return {
internalName: undefined,
internalRoles: undefined,
unsupportedRoles: undefined,
errorMessage: undefined,
detailedErrorMessage: undefined
}
Expand Down Expand Up @@ -200,11 +204,8 @@ export default {
isUpdateDialog () {
return this.type === 'updateuser' || this.type === 'updateservice'
},
textField () {
return this.$refs.internalName
},
roleItems () {
return filter(MEMBER_ROLE_DESCRIPTORS, role => role.hidden !== true)
return MEMBER_ROLE_DESCRIPTORS
},
nameLabel () {
return this.isUserDialog ? 'User' : 'Service Account'
Expand Down Expand Up @@ -287,7 +288,7 @@ export default {
if (this.valid) {
try {
const name = this.memberName
const roles = this.internalRoles
const roles = [...this.internalRoles, ...this.unsupportedRoles]
await this.updateMember({ name, roles })
if (this.isCurrentUser && !this.isAdmin) {
await this.refreshSubjectRules()
Expand Down Expand Up @@ -323,9 +324,18 @@ export default {
}
if (this.roles) {
this.internalRoles = [...this.roles]
this.internalRoles = []
this.unsupportedRoles = []
forEach(this.roles, role => {
if (find(this.roleItems, { name: role })) {
this.internalRoles.push(role)
} else {
this.unsupportedRoles.push(role)
}
})
} else {
this.internalRoles = [defaultRole]
this.unsupportedRoles = []
}
this.errorMessage = undefined
Expand All @@ -334,9 +344,7 @@ export default {
this.setFocusAndSelection()
},
setFocusAndSelection () {
if (this.textField) {
setInputFocus(this, 'name')
}
setDelayedInputFocus(this, 'internalName')
},
defaultServiceName () {
let name = defaultServiceName
Expand All @@ -355,12 +363,6 @@ export default {
this.reset()
}
}
},
mounted () {
if (this.textField) {
const input = this.textField.$refs.input
input.style.textTransform = 'lowercase'
}
}
}
</script>
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/utils/index.js
Expand Up @@ -689,11 +689,6 @@ export const MEMBER_ROLE_DESCRIPTORS = [
{
name: 'viewer',
displayName: 'Viewer'
},
{
name: 'owner',
displayName: 'Technical Contact',
hidden: true // Do not show on UI as currently cannot be modified
}
]

Expand Down
6 changes: 1 addition & 5 deletions frontend/src/views/Members.vue
Expand Up @@ -209,7 +209,6 @@ import forEach from 'lodash/forEach'
import join from 'lodash/join'
import map from 'lodash/map'
import find from 'lodash/find'
import upperFirst from 'lodash/upperFirst'
import escape from 'lodash/escape'
import MemberDialog from '@/components/dialogs/MemberDialog'
import MemberHelpDialog from '@/components/dialogs/MemberHelpDialog'
Expand Down Expand Up @@ -455,10 +454,7 @@ export default {
const displayNames = []
forEach(roleNames, roleName => {
const roleDescriptor = find(MEMBER_ROLE_DESCRIPTORS, { name: roleName })
if (!roleDescriptor) {
displayNames.push(upperFirst(roleName))
}
if (!roleDescriptor.hidden) {
if (roleDescriptor) {
displayNames.push(roleDescriptor.displayName)
}
})
Expand Down
26 changes: 2 additions & 24 deletions frontend/src/views/Secrets.vue
Expand Up @@ -73,11 +73,7 @@ limitations under the License.
@toogleHelp="onToogleHelp"
@update="onUpdate"
@delete="onDelete"
>
<template v-if="isOwnSecretBinding(secret)" v-slot:rowSubTitle="{ secret }">
{{secret.data.domainName}} / {{secret.data.tenantName}}
</template>
</secret>
></secret>

<secret
v-if="hasCloudProfileForCloudProviderKind('alicloud')"
Expand Down Expand Up @@ -122,21 +118,7 @@ limitations under the License.
@toogleHelp="onToogleHelp"
@update="onUpdate"
@delete="onDelete"
>
<template v-if="isOwnSecretBinding(secret)" v-slot:rowSubTitle="{ secret }">
<v-tooltip top>
<template v-slot:activator="{ on }">
<span v-on="on">{{secret.data.vsphereUsername}}</span>
</template>
<span>vSphere Username</span>
</v-tooltip> / <v-tooltip top>
<template v-slot:activator="{ on }">
<span v-on="on">{{secret.data.nsxtUsername}}</span>
</template>
<span>NSX-T Username</span>
</v-tooltip>
</template>
</secret>
></secret>

<template v-if="showDisabledCloudProviders">

Expand Down Expand Up @@ -206,7 +188,6 @@ limitations under the License.
<script>
import { mapGetters } from 'vuex'
import get from 'lodash/get'
import { isOwnSecretBinding } from '@/utils'
import DeleteDialog from '@/components/dialogs/SecretDialogDelete'
import SecretDialogWrapper from '@/components/dialogs/SecretDialogWrapper'
import Secret from '@/components/Secret'
Expand Down Expand Up @@ -323,9 +304,6 @@ export default {
},
hideDialogs () {
merge(this.dialogState, this.initialDialogState)
},
isOwnSecretBinding (secret) {
return isOwnSecretBinding(secret)
}
},
mounted () {
Expand Down

0 comments on commit ef90078

Please sign in to comment.