mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-15 09:34:13 +00:00
Resolve "Show disabled RBAC roles when not available"
This commit is contained in:
parent
6cd0d63bb4
commit
a602bb1ea7
19 changed files with 560 additions and 57 deletions
changelog/entries/unreleased/feature
enterprise/web-frontend/modules/baserow_enterprise
web-frontend/modules
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "feature",
|
||||
"message": "Display unavailable advanced/enterprise roles even if the user isn't on one of these plans",
|
||||
"issue_number": 1313,
|
||||
"bullet_points": [],
|
||||
"created_at": "2024-03-27"
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
ref="editRoleContext"
|
||||
:subject="rowSanitised"
|
||||
:roles="roles"
|
||||
:workspace="workspace"
|
||||
role-value-column="permissions"
|
||||
@update-role="roleUpdate($event)"
|
||||
></EditRoleContext>
|
||||
|
@ -51,7 +52,9 @@ export default {
|
|||
rowSanitised() {
|
||||
return {
|
||||
...this.row,
|
||||
permissions: this.roles.some(({ uid }) => uid === this.row.permissions)
|
||||
permissions: this.roles.some(
|
||||
(role) => role.uid === this.row.permissions
|
||||
)
|
||||
? this.row.permissions
|
||||
: 'BUILDER',
|
||||
}
|
||||
|
|
|
@ -36,9 +36,6 @@ export default {
|
|||
role() {
|
||||
return this.roles.find((r) => r.uid === this.roleUID)
|
||||
},
|
||||
roleIsBillable() {
|
||||
return this?.role.isBillable
|
||||
},
|
||||
workspace() {
|
||||
return this.$store.getters['workspace/get'](
|
||||
this.column.additionalProps.workspaceId
|
||||
|
|
|
@ -1,24 +1,53 @@
|
|||
<template>
|
||||
<div>
|
||||
<a class="context__menu-item-link" @click="() => $refs.modal.show()">
|
||||
<i class="context__menu-item-icon iconoir-community"></i
|
||||
>{{ $t('memberRolesDatabaseContexItem.label') }}</a
|
||||
<a
|
||||
class="context__menu-item-link"
|
||||
@click="
|
||||
() => {
|
||||
if (deactivated) {
|
||||
$refs.premiumModal.show()
|
||||
} else {
|
||||
$refs.memberRolesModal.show()
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<MemberRolesModal ref="modal" :database="application" />
|
||||
<i class="context__menu-item-icon iconoir-community"></i>
|
||||
{{ $t('memberRolesDatabaseContexItem.label') }}
|
||||
<div v-if="deactivated" class="deactivated-label">
|
||||
<i class="iconoir-lock"></i>
|
||||
</div>
|
||||
</a>
|
||||
<MemberRolesModal ref="memberRolesModal" :database="application" />
|
||||
<PremiumModal
|
||||
ref="premiumModal"
|
||||
:name="$t('memberRolesDatabaseContexItem.additionalRoles')"
|
||||
:workspace="application.workspace"
|
||||
></PremiumModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MemberRolesModal from '@baserow_enterprise/components/member-roles/MemberRolesModal'
|
||||
import EnterpriseFeatures from '@baserow_enterprise/features'
|
||||
import PremiumModal from '@baserow_premium/components/PremiumModal'
|
||||
|
||||
export default {
|
||||
name: 'MemberRolesDatabaseContextItem',
|
||||
components: { MemberRolesModal },
|
||||
components: { MemberRolesModal, PremiumModal },
|
||||
props: {
|
||||
application: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
deactivated() {
|
||||
return !this.$hasFeature(
|
||||
EnterpriseFeatures.RBAC,
|
||||
this.application.workspace.id
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,21 +1,46 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="context__menu-item" @click="() => $refs.modal.show()">
|
||||
<a class="context__menu-item-link">
|
||||
<i class="context__menu-item-icon iconoir-community"></i
|
||||
>{{ $t('memberRolesTableContexItem.label') }}</a
|
||||
<div class="context__menu-item">
|
||||
<a
|
||||
class="context__menu-item-link"
|
||||
@click="
|
||||
() => {
|
||||
if (deactivated) {
|
||||
$refs.premiumModal.show()
|
||||
} else {
|
||||
$refs.memberRolesModal.show()
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<i class="context__menu-item-icon iconoir-community"></i>
|
||||
{{ $t('memberRolesDatabaseContexItem.label') }}
|
||||
<div v-if="deactivated" class="deactivated-label">
|
||||
<i class="iconoir-lock"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<MemberRolesModal ref="modal" :database="database" :table="table" />
|
||||
<MemberRolesModal
|
||||
ref="memberRolesModal"
|
||||
:database="database"
|
||||
:table="table"
|
||||
/>
|
||||
<PremiumModal
|
||||
ref="premiumModal"
|
||||
:name="$t('memberRolesTableContexItem.additionalRoles')"
|
||||
:workspace="database.workspace"
|
||||
></PremiumModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MemberRolesModal from '@baserow_enterprise/components/member-roles/MemberRolesModal'
|
||||
import EnterpriseFeatures from '@baserow_enterprise/features'
|
||||
import PremiumModal from '@baserow_premium/components/PremiumModal'
|
||||
|
||||
export default {
|
||||
name: 'MemberRolesTableContextItem',
|
||||
components: { MemberRolesModal },
|
||||
components: { MemberRolesModal, PremiumModal },
|
||||
props: {
|
||||
table: {
|
||||
type: Object,
|
||||
|
@ -26,5 +51,13 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
deactivated() {
|
||||
return !this.$hasFeature(
|
||||
EnterpriseFeatures.RBAC,
|
||||
this.database.workspace.id
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -49,7 +49,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
roleUpdated({ uid }) {
|
||||
const role = this.roles.find((role) => role.uid === uid)
|
||||
const role = this.roles.find((role) => role.getUid() === uid)
|
||||
this.$emit('input', role)
|
||||
},
|
||||
},
|
||||
|
|
|
@ -209,10 +209,12 @@
|
|||
"subLabel": "{totalUserAmount} workspace members"
|
||||
},
|
||||
"memberRolesDatabaseContexItem": {
|
||||
"label": "Manage members"
|
||||
"label": "Manage members",
|
||||
"additionalRoles": "Additional roles"
|
||||
},
|
||||
"memberRolesTableContexItem": {
|
||||
"label": "Manage members"
|
||||
"label": "Manage members",
|
||||
"additionalRoles": "Additional roles"
|
||||
},
|
||||
"memberRolesMembersList": {
|
||||
"remove": "Remove",
|
||||
|
|
|
@ -28,6 +28,16 @@ import { EnterprisePlugin } from '@baserow_enterprise/plugins'
|
|||
import { LocalBaserowUserSourceType } from '@baserow_enterprise/integrations/userSourceTypes'
|
||||
import { LocalBaserowPasswordAppAuthProviderType } from '@baserow_enterprise/integrations/appAuthProviderTypes'
|
||||
import { AuthFormElementType } from '@baserow_enterprise/builder/elementTypes'
|
||||
import {
|
||||
EnterpriseAdminRoleType,
|
||||
EnterpriseMemberRoleType,
|
||||
EnterpriseBuilderRoleType,
|
||||
EnterpriseEditorRoleType,
|
||||
EnterpriseCommenterRoleType,
|
||||
EnterpriseViewerRoleType,
|
||||
NoAccessRoleType,
|
||||
NoRoleLowPriorityRoleType,
|
||||
} from '@baserow_enterprise/roleTypes'
|
||||
|
||||
export default (context) => {
|
||||
const { app, isDev, store } = context
|
||||
|
@ -97,5 +107,14 @@ export default (context) => {
|
|||
new LocalBaserowPasswordAppAuthProviderType(context)
|
||||
)
|
||||
|
||||
app.$registry.register('roles', new EnterpriseAdminRoleType(context))
|
||||
app.$registry.register('roles', new EnterpriseMemberRoleType(context))
|
||||
app.$registry.register('roles', new EnterpriseBuilderRoleType(context))
|
||||
app.$registry.register('roles', new EnterpriseEditorRoleType(context))
|
||||
app.$registry.register('roles', new EnterpriseCommenterRoleType(context))
|
||||
app.$registry.register('roles', new EnterpriseViewerRoleType(context))
|
||||
app.$registry.register('roles', new NoAccessRoleType(context))
|
||||
app.$registry.register('roles', new NoRoleLowPriorityRoleType(context))
|
||||
|
||||
app.$registry.register('element', new AuthFormElementType(context))
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ export class EnterprisePlugin extends BaserowPlugin {
|
|||
|
||||
getAdditionalDatabaseContextComponents(workspace, database) {
|
||||
if (
|
||||
this.app.$hasFeature(EnterpriseFeatures.RBAC, workspace.id) &&
|
||||
this.app.$hasPermission('application.read_role', database, workspace.id)
|
||||
) {
|
||||
return [MemberRolesDatabaseContextItem]
|
||||
|
@ -40,7 +39,6 @@ export class EnterprisePlugin extends BaserowPlugin {
|
|||
|
||||
getAdditionalTableContextComponents(workspace, table) {
|
||||
if (
|
||||
this.app.$hasFeature(EnterpriseFeatures.RBAC, workspace.id) &&
|
||||
this.app.$hasPermission('database.table.read_role', table, workspace.id)
|
||||
) {
|
||||
return [MemberRolesTableContextItem]
|
||||
|
|
243
enterprise/web-frontend/modules/baserow_enterprise/roleTypes.js
Normal file
243
enterprise/web-frontend/modules/baserow_enterprise/roleTypes.js
Normal file
|
@ -0,0 +1,243 @@
|
|||
import {
|
||||
AdminRoleType,
|
||||
MemberRoleType,
|
||||
} from '@baserow/modules/database/roleTypes'
|
||||
import PremiumModal from '@baserow_premium/components/PremiumModal'
|
||||
import EnterpriseFeatures from '@baserow_enterprise/features'
|
||||
|
||||
export class EnterpriseAdminRoleType extends AdminRoleType {
|
||||
showIsBillable(workspaceId) {
|
||||
return this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
}
|
||||
|
||||
export class EnterpriseMemberRoleType extends MemberRoleType {
|
||||
// This role doesn't exist in enterprise, so we hide it completely.
|
||||
isVisible(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
}
|
||||
|
||||
export class EnterpriseBuilderRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'builder'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'BUILDER'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.builder.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.builder.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
isVisible(workspaceId) {
|
||||
return this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal() {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
||||
|
||||
export class EnterpriseEditorRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'editor'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'EDITOR'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.editor.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.editor.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
||||
|
||||
export class EnterpriseCommenterRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'commenter'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'COMMENTER'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.commenter.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.commenter.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
||||
|
||||
export class EnterpriseViewerRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'viewer'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'VIEWER'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.viewer.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.viewer.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
||||
|
||||
export class NoAccessRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'noAccess'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'NO_ACCESS'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.noAccess.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.noAccess.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
||||
|
||||
export class NoRoleLowPriorityRoleType extends MemberRoleType {
|
||||
getType() {
|
||||
return 'noRoleLowPriority'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'NO_ROLE_LOW_PRIORITY'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.noRoleLowPriority.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.noRoleLowPriority.description')
|
||||
}
|
||||
|
||||
showIsBillable(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
getIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
isDeactivated(workspaceId) {
|
||||
return !this.app.$hasFeature(EnterpriseFeatures.RBAC, workspaceId)
|
||||
}
|
||||
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return PremiumModal
|
||||
}
|
||||
}
|
|
@ -21,24 +21,44 @@
|
|||
</div>
|
||||
</div>
|
||||
<ul class="context__menu context__menu--can-be-active">
|
||||
<li v-for="role in roles" :key="role.uid" class="context__menu-item">
|
||||
<li
|
||||
v-for="(role, index) in visibleRoles"
|
||||
:key="index"
|
||||
class="context__menu-item"
|
||||
>
|
||||
<a
|
||||
class="context__menu-item-link context__menu-item-link--with-desc"
|
||||
:class="{ active: subject[roleValueColumn] === role.uid }"
|
||||
@click="roleUpdate(role.uid, subject)"
|
||||
:class="{
|
||||
active: subject[roleValueColumn] === role.uid,
|
||||
disabled: role.isDeactivated,
|
||||
}"
|
||||
@click="
|
||||
!role.isDeactivated
|
||||
? roleUpdate(role.uid, subject)
|
||||
: clickOnDeactivatedItem(role.uid)
|
||||
"
|
||||
>
|
||||
<span class="context__menu-item-title">
|
||||
{{ role.name }}
|
||||
<Badge v-if="role.isBillable" color="cyan" size="small" bold
|
||||
<Badge
|
||||
v-if="role.showIsBillable && role.isBillable"
|
||||
color="cyan"
|
||||
size="small"
|
||||
bold
|
||||
>{{ $t('common.billable') }}
|
||||
</Badge>
|
||||
<Badge
|
||||
v-else-if="!role.isBillable && atLeastOneBillableRole"
|
||||
v-else-if="
|
||||
role.showIsBillable &&
|
||||
!role.isBillable &&
|
||||
atLeastOneBillableRole
|
||||
"
|
||||
color="yellow"
|
||||
size="small"
|
||||
bold
|
||||
>{{ $t('common.free') }}
|
||||
</Badge>
|
||||
<i v-if="role.isDeactivated" class="iconoir-lock"></i>
|
||||
</span>
|
||||
<div v-if="role.description" class="context__menu-item-description">
|
||||
{{ role.description }}
|
||||
|
@ -48,6 +68,13 @@
|
|||
class="context__menu-active-icon iconoir-check"
|
||||
></i>
|
||||
</a>
|
||||
<component
|
||||
:is="deactivatedClickModal(role)"
|
||||
:ref="'deactivatedClickModal-' + role.uid"
|
||||
:v-if="deactivatedClickModal(role)"
|
||||
:name="$t('editRoleContext.additionalRoles')"
|
||||
:workspace="workspace"
|
||||
></component>
|
||||
</li>
|
||||
<li
|
||||
v-if="allowRemovingRole"
|
||||
|
@ -71,6 +98,11 @@ export default {
|
|||
name: 'EditRoleContext',
|
||||
mixins: [context],
|
||||
props: {
|
||||
workspace: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
subject: {
|
||||
required: true,
|
||||
type: Object,
|
||||
|
@ -90,6 +122,9 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
visibleRoles() {
|
||||
return this.roles.filter((role) => role.isVisible)
|
||||
},
|
||||
atLeastOneBillableRole() {
|
||||
return this.roles.some((role) => role.isBillable)
|
||||
},
|
||||
|
@ -103,6 +138,15 @@ export default {
|
|||
this.$emit('update-role', { uid: roleNew, subject })
|
||||
this.hide()
|
||||
},
|
||||
deactivatedClickModal(role) {
|
||||
const allRoles = Object.values(this.$registry.getAll('roles'))
|
||||
return allRoles
|
||||
.find((r) => r.getUid() === role.uid)
|
||||
.getDeactivatedClickModal()
|
||||
},
|
||||
clickOnDeactivatedItem(value) {
|
||||
this.$refs[`deactivatedClickModal-${value}`][0].show()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
ref="editRoleContext"
|
||||
:subject="editRoleMember"
|
||||
:roles="roles"
|
||||
:workspace="workspace"
|
||||
@update-role="roleUpdate($event)"
|
||||
></EditRoleContext>
|
||||
</template>
|
||||
|
|
|
@ -28,27 +28,47 @@
|
|||
v-model="values.permissions"
|
||||
class="group-invite-form__role-selector-dropdown"
|
||||
:show-search="false"
|
||||
:fixed-items="true"
|
||||
small
|
||||
>
|
||||
<DropdownItem
|
||||
v-for="role in roles"
|
||||
:key="role.uid"
|
||||
v-for="(role, index) in roles"
|
||||
:key="index"
|
||||
:ref="'role' + role.uid"
|
||||
:name="role.name"
|
||||
:value="role.uid"
|
||||
:disabled="role.isDeactivated"
|
||||
:description="role.description"
|
||||
@click="clickOnDeactivatedItem($event)"
|
||||
>
|
||||
{{ role.name }}
|
||||
<Badge v-if="role.isBillable" color="cyan" size="small" bold
|
||||
<Badge
|
||||
v-if="role.showIsBillable && role.isBillable"
|
||||
color="cyan"
|
||||
size="small"
|
||||
bold
|
||||
>{{ $t('common.billable') }}
|
||||
</Badge>
|
||||
<Badge
|
||||
v-else-if="!role.isBillable && atLeastOneBillableRole"
|
||||
v-else-if="
|
||||
role.showIsBillable &&
|
||||
!role.isBillable &&
|
||||
atLeastOneBillableRole
|
||||
"
|
||||
color="yellow"
|
||||
size="small"
|
||||
bold
|
||||
class="margin-left-1"
|
||||
>{{ $t('common.free') }}
|
||||
</Badge>
|
||||
<i v-if="role.isDeactivated" class="iconoir-lock"></i>
|
||||
<component
|
||||
:is="deactivatedClickModal(role)"
|
||||
:ref="'deactivatedClickModal-' + role.uid"
|
||||
:v-if="deactivatedClickModal(role)"
|
||||
:name="$t('workspaceInviteForm.additionalRoles')"
|
||||
:workspace="workspace"
|
||||
></component>
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
@ -113,10 +133,11 @@ export default {
|
|||
return MESSAGE_MAX_LENGTH
|
||||
},
|
||||
roles() {
|
||||
return this.workspace._.roles
|
||||
return this.workspace._.roles.filter((role) => role.isVisible)
|
||||
},
|
||||
defaultRole() {
|
||||
return this.roles.length > 0 ? this.roles[this.roles.length - 1] : null
|
||||
const activeRoles = this.roles.filter((role) => !role.isDeactivated)
|
||||
return activeRoles.length > 0 ? activeRoles[activeRoles.length - 1] : null
|
||||
},
|
||||
atLeastOneBillableRole() {
|
||||
return this.roles.some((role) => role.isBillable)
|
||||
|
@ -130,6 +151,20 @@ export default {
|
|||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
deactivatedClickModal(role) {
|
||||
const allRoles = Object.values(this.$registry.getAll('roles'))
|
||||
return allRoles
|
||||
.find((r) => r.getUid() === role.uid)
|
||||
.getDeactivatedClickModal()
|
||||
},
|
||||
clickOnDeactivatedItem(value) {
|
||||
const role = this.roles.find((role) => role.uid === value)
|
||||
if (role && role.isDeactivated) {
|
||||
this.$refs[`deactivatedClickModal-${value}`][0].show()
|
||||
}
|
||||
},
|
||||
},
|
||||
validations: {
|
||||
values: {
|
||||
email: { required, email },
|
||||
|
|
|
@ -134,7 +134,8 @@
|
|||
"invitationFormTitle": "Invite by email",
|
||||
"optionalMessagePlaceholder": "Optional message",
|
||||
"errorInvalidEmail": "Please enter a valid e-mail address.",
|
||||
"errorTooLongMessage": "Messages are limited to {amount} characters."
|
||||
"errorTooLongMessage": "Messages are limited to {amount} characters.",
|
||||
"additionalRoles": "Additional roles"
|
||||
},
|
||||
"workspacesContext": {
|
||||
"search": "Search workspaces",
|
||||
|
@ -528,7 +529,8 @@
|
|||
"remove": "Remove"
|
||||
},
|
||||
"editRoleContext": {
|
||||
"billableRolesLink": "Billable roles documentation"
|
||||
"billableRolesLink": "Billable roles documentation",
|
||||
"additionalRoles": "Additional roles"
|
||||
},
|
||||
"highestPaidRoleField": {
|
||||
"billable": "Billable"
|
||||
|
|
|
@ -49,6 +49,7 @@ export default {
|
|||
if (!disabled) {
|
||||
this.$parent.select(value)
|
||||
}
|
||||
this.$emit('click', value)
|
||||
},
|
||||
hover(value, disabled) {
|
||||
if (!disabled && this.$parent.hover !== value) {
|
||||
|
|
|
@ -71,6 +71,11 @@ import {
|
|||
|
||||
import priorityBus from '@baserow/modules/core/plugins/priorityBus'
|
||||
|
||||
import {
|
||||
AdminRoleType,
|
||||
MemberRoleType,
|
||||
} from '@baserow/modules/database/roleTypes'
|
||||
|
||||
export default (context, inject) => {
|
||||
const { store, isDev, app } = context
|
||||
inject('bus', new Vue())
|
||||
|
@ -106,6 +111,7 @@ export default (context, inject) => {
|
|||
registry.registerNamespace('service')
|
||||
registry.registerNamespace('userSource')
|
||||
registry.registerNamespace('appAuthProvider')
|
||||
registry.registerNamespace('roles')
|
||||
|
||||
registry.register('settings', new AccountSettingsType(context))
|
||||
registry.register('settings', new PasswordSettingsType(context))
|
||||
|
@ -170,6 +176,9 @@ export default (context, inject) => {
|
|||
registry.register('runtimeFormulaFunction', new RuntimeGet(context))
|
||||
registry.register('runtimeFormulaFunction', new RuntimeAdd(context))
|
||||
|
||||
registry.register('roles', new AdminRoleType(context))
|
||||
registry.register('roles', new MemberRoleType(context))
|
||||
|
||||
// Notification types
|
||||
registry.register(
|
||||
'notification',
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
export default (client, $hasFeature) => {
|
||||
export default (client, $hasFeature, $registry) => {
|
||||
return {
|
||||
// TODO implement once endpoint exists
|
||||
get(workspace) {
|
||||
if ($hasFeature('RBAC', workspace.id)) {
|
||||
return {
|
||||
data: [
|
||||
{ uid: 'ADMIN', isBillable: true },
|
||||
{ uid: 'BUILDER', isBillable: true },
|
||||
{ uid: 'EDITOR', isBillable: true },
|
||||
{ uid: 'COMMENTER', isBillable: false },
|
||||
{ uid: 'VIEWER', isBillable: false },
|
||||
{ uid: 'NO_ACCESS', isBillable: false },
|
||||
{
|
||||
uid: 'NO_ROLE_LOW_PRIORITY',
|
||||
allowed_scope_types: ['workspace'],
|
||||
allowed_subject_types: ['auth.User'],
|
||||
isBillable: false,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
return {
|
||||
data: [
|
||||
{ uid: 'ADMIN', isBillable: false },
|
||||
{ uid: 'MEMBER', isBillable: false },
|
||||
],
|
||||
data: Object.values($registry.getAll('roles')).map((role) =>
|
||||
role.getUid() === 'NO_ROLE_LOW_PRIORITY'
|
||||
? {
|
||||
uid: role.getUid(),
|
||||
description: role.getDescription(),
|
||||
showIsBillable: role.showIsBillable(workspace.id),
|
||||
isBillable: role.getIsBillable(workspace.id),
|
||||
isVisible: role.isVisible(workspace.id),
|
||||
isDeactivated: role.isDeactivated(),
|
||||
allowed_scope_types: ['workspace'],
|
||||
allowed_subject_types: ['auth.User'],
|
||||
}
|
||||
: {
|
||||
uid: role.getUid(),
|
||||
description: role.getDescription(),
|
||||
showIsBillable: role.showIsBillable(workspace.id),
|
||||
isBillable: role.getIsBillable(workspace.id),
|
||||
isVisible: role.isVisible(workspace.id),
|
||||
isDeactivated: role.isDeactivated(),
|
||||
}
|
||||
),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -355,7 +355,8 @@ export const actions = {
|
|||
try {
|
||||
const { data } = await RolesService(
|
||||
this.$client,
|
||||
this.app.$hasFeature
|
||||
this.app.$hasFeature,
|
||||
this.$registry
|
||||
).get(workspace)
|
||||
const translatedRoles = appendRoleTranslations(data, this.app.$registry)
|
||||
commit('SET_ROLES', { workspaceId: workspace.id, roles: translatedRoles })
|
||||
|
|
80
web-frontend/modules/database/roleTypes.js
Normal file
80
web-frontend/modules/database/roleTypes.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { Registerable } from '@baserow/modules/core/registry'
|
||||
|
||||
class RoleType extends Registerable {
|
||||
getUid() {
|
||||
return null
|
||||
}
|
||||
|
||||
getName() {
|
||||
return null
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
return null
|
||||
}
|
||||
|
||||
// Indicates weather to show the role as billable/non-billable or show nothing.
|
||||
showIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Indicates whether the role is billable.
|
||||
getIsBillable(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Indicates whether the role should be visible in the list.
|
||||
isVisible(workspaceId) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Indicates whether the role is visible, but in a deactivated state.
|
||||
isDeactivated(workspaceId) {
|
||||
return false
|
||||
}
|
||||
|
||||
// The modal component that must be shown when a deactivated role is clicked.
|
||||
getDeactivatedClickModal(workspaceId) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export class AdminRoleType extends RoleType {
|
||||
getType() {
|
||||
return 'admin'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'ADMIN'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.admin.name')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('roles.admin.description')
|
||||
}
|
||||
}
|
||||
|
||||
export class MemberRoleType extends RoleType {
|
||||
getType() {
|
||||
return 'member'
|
||||
}
|
||||
|
||||
getUid() {
|
||||
return 'MEMBER'
|
||||
}
|
||||
|
||||
getName() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('permission.member')
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
const { i18n } = this.app
|
||||
return i18n.t('permission.memberDescription')
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue