Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion auth-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "auth-web",
"version": "2.7.0",
"version": "2.7.1",
"appName": "Auth Web",
"sbcName": "SBC Common Components",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@
</template>

<script lang="ts">
import { AccessType, AccountStatus, Pages, Permission, Role, SuspensionReason } from '@/util/constants'
import { AccessType, AccountStatus, Permission, Role, SuspensionReason } from '@/util/constants'
import { CreateRequestBody, OrgBusinessType } from '@/models/Organization'
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, toRefs } from '@vue/composition-api'
import { useAccount, useAccountChangeHandler } from '@/composables'
Expand Down Expand Up @@ -361,16 +361,15 @@ export default defineComponent({
isBusinessAccount: computed(() => orgStore.isBusinessAccount),
baseAddress: computed(() => currentOrgAddress.value),

isStaff: computed(() => userStore.currentUser.roles.includes(Role.Staff)),
isStaff: computed(() => userStore.currentUser.roles.includes(Role.Staff)) || userStore.currentUser.roles.includes(Role.ContactCentreStaff),
isSuspendButtonVisible: computed(() => (
(currentOrganization.value.statusCode === AccountStatus.ACTIVE ||
currentOrganization.value.statusCode === AccountStatus.SUSPENDED) &&
userStore.currentUser.roles.includes(Role.StaffSuspendAccounts)
)),
isDeactivateButtonVisible: computed(() => currentOrganization.value?.statusCode !== AccountStatus.INACTIVE),
editAccountUrl: Pages.EDIT_ACCOUNT_TYPE,
canChangeAccessType: computed(() => userStore.currentUser.roles.includes(Role.StaffManageAccounts)),
isAddressEditable: computed(() => [Permission.CHANGE_ADDRESS].some(per => permissions.value.includes(per))),
canChangeAccessType: computed(() => userStore.currentUser.roles.includes(Role.StaffManageAccounts)) &&
!userStore.currentUser.roles.includes(Role.ContactCentreStaff),
isAdminContactViewable: computed(() => [Permission.VIEW_ADMIN_CONTACT].some(per => permissions.value.includes(per))),
isAccountStatusActive: computed(() => currentOrganization.value.statusCode === AccountStatus.ACTIVE),
accountType: computed(() => {
Expand All @@ -384,7 +383,8 @@ export default defineComponent({
isAddressInfoIncomplete: computed(() => (
currentOrgAddress.value ? Object.keys(currentOrgAddress.value).length === 0 : true
)),
nameChangeNotAllowed: computed(() => (anonAccount.value || isGovmAccount.value))
nameChangeNotAllowed: computed(() => (anonAccount.value || isGovmAccount.value)) &&
userStore.currentUser.roles.includes(Role.ContactCentreStaff)
})

const suspensionSelectRules = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
v-can:CHANGE_ADDRESS.hide
>
<span
v-if="canChangeAddress"
class="primary--text cursor-pointer"
data-test="btn-edit"
@click="$emit('update:viewOnlyMode', {component:'address',mode:false })"
Expand Down Expand Up @@ -79,9 +80,11 @@
</template>

<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api'
import { computed, defineComponent, ref } from '@vue/composition-api'
import BaseAddressForm from '@/components/auth/common/BaseAddressForm.vue'
import { Role } from '@/util/constants'
import { addressSchema } from '@/schemas'
import { useUserStore } from '@/stores/user'

export default defineComponent({
name: 'AccountMailingAddress',
Expand All @@ -100,10 +103,13 @@ export default defineComponent({
},
emit: ['valid', 'update:address'],
setup (props, { emit }) {
const { currentUser } = useUserStore()
const baseAddressSchema = ref(addressSchema)

const mailingAddress = ref<HTMLFormElement | null>(null)

const canChangeAddress = computed(() => !currentUser?.roles?.includes(Role.ContactCentreStaff))

function updateAddress (address) {
emit('update:address', address)
}
Expand All @@ -122,7 +128,8 @@ export default defineComponent({
mailingAddress,
updateAddress,
checkBaseAddressValidity,
triggerValidate
triggerValidate,
canChangeAddress
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<template #[`item.action`]="{ item }">
<!-- Resend Invitation -->
<v-btn
v-if="canDoActions"
icon
class="mr-1"
aria-label="Resend invitation"
Expand All @@ -42,6 +43,7 @@

<!-- Remove Invitation -->
<v-btn
v-if="canDoActions"
icon
aria-label="Remove Invitation"
title="Remove Invitation"
Expand All @@ -58,16 +60,22 @@
import { Component, Emit, Vue } from 'vue-property-decorator'
import CommonUtils from '@/util/common-util'
import { Invitation } from '@/models/Invitation'
import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile'
import { Role } from '@/util/constants'
import { mapState } from 'pinia'
import { useOrgStore } from '@/stores/org'
import { useUserStore } from '@/stores/user'

@Component({
computed: {
...mapState(useOrgStore, ['pendingOrgInvitations'])
...mapState(useOrgStore, ['pendingOrgInvitations']),
...mapState(useUserStore, ['currentUser'])
}
})
export default class InvitationsDataTable extends Vue {
private readonly pendingOrgInvitations!: Invitation[]
readonly currentUser!: KCUserProfile
canDoActions: boolean = false
readonly headerInvitations = [
{
text: 'Email',
Expand Down Expand Up @@ -95,6 +103,10 @@ export default class InvitationsDataTable extends Vue {
}
]

public mounted () {
this.canDoActions = !this.currentUser?.roles?.includes(Role.ContactCentreStaff)
Copy link
Collaborator

@ochiu ochiu Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to just abstract this a bit since we are re-using v-can and the common utils Permissions?
We can add a permission there and not need to add the role check here specifically?

^ The above applies to other places as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed transactions, and moved logic to permissions and v-can:

}

formatDate = CommonUtils.formatDisplayDate

getIndexedTag (tag, index): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
<!-- Remove User -->
<v-btn
v-show="canRemove(item)"
v-can:REMOVE_TEAM_MEMBER.hide
icon
aria-label="Remove Team Member"
title="Remove Team Member"
Expand Down Expand Up @@ -231,12 +232,13 @@
</template>

<script lang="ts">
import { AccessType, LoginSource, Permission } from '@/util/constants'
import { AccessType, LoginSource, Permission, Role } from '@/util/constants'
import { Component, Emit, Prop, Vue } from 'vue-property-decorator'
import { Member, MembershipStatus, MembershipType, Organization, RoleInfo } from '@/models/Organization'
import { mapActions, mapState } from 'pinia'
import { Business } from '@/models/business'
import CommonUtils from '@/util/common-util'
import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile'
import ModalDialog from '@/components/auth/common/ModalDialog.vue'
import { useBusinessStore } from '@/stores/business'
import { useOrgStore } from '@/stores/org'
Expand All @@ -260,6 +262,7 @@ export interface ChangeRolePayload {
'permissions'
]),
...mapState(useUserStore, [
'currentUser',
'roleInfos'
])
},
Expand All @@ -272,6 +275,7 @@ export interface ChangeRolePayload {
})
export default class MemberDataTable extends Vue {
@Prop({ default: '' }) private userNamefilterText: string
protected readonly currentUser!: KCUserProfile
private readonly businesses!: Business[]
private activeOrgMembers!: Member[]
private readonly currentMembership!: Member
Expand Down Expand Up @@ -401,16 +405,18 @@ export default class MemberDataTable extends Vue {
}

private canChangeRole (memberBeingChanged: Member): boolean {
if (this.currentUser.roles?.includes(Role.ContactCentreStaff)) {
return false
}

if (this.currentMembership.membershipStatus !== MembershipStatus.Active) {
return false
}

switch (this.currentMembership.membershipTypeCode) {
case MembershipType.Admin:
// Owners can change roles of other users who are not owners
if (
!this.isOwnMembership(memberBeingChanged)
) {
if (!this.isOwnMembership(memberBeingChanged)) {
return true
}
// And they can downgrade their own role if there is another owner on the team
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</template>
<template #[`item.action`]="{ item }">
<v-btn
v-if="canDoActions"
icon
class="mr-1"
aria-label="Approve user access to this account"
Expand All @@ -38,6 +39,7 @@
<v-icon>mdi-check-circle-outline</v-icon>
</v-btn>
<v-btn
v-if="canDoActions"
icon
aria-label="Deny access to this account"
title="Deny access to this account"
Expand All @@ -52,20 +54,26 @@

<script lang="ts">
import { Component, Emit, Prop, Vue } from 'vue-property-decorator'
import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile'
import { Member } from '@/models/Organization'
import { Role } from '@/util/constants'
import { mapState } from 'pinia'
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
import moment from 'moment'
import { useOrgStore } from '@/stores/org'
import { useUserStore } from '@/stores/user'

@Component({
computed: {
...mapState(useOrgStore, ['pendingOrgMembers'])
...mapState(useOrgStore, ['pendingOrgMembers']),
...mapState(useUserStore, ['currentUser'])
}
})
export default class PendingMemberDataTable extends Vue {
@Prop({ default: '' }) userNamefilterText: string
readonly pendingOrgMembers!: Member[]
readonly currentUser!: KCUserProfile
canDoActions: boolean = false
readonly headerPendingMembers = [
{
text: 'Team Member',
Expand All @@ -81,6 +89,10 @@ export default class PendingMemberDataTable extends Vue {
}
]

public mounted () {
this.canDoActions = !this.currentUser?.roles?.includes(Role.ContactCentreStaff)
}

getIndexedTag (tag, index): string {
return `${tag}-${index}`
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
Active
</v-tab>
<v-tab
v-can:INVITE_MEMBERS.hide
data-test="pending-approval-tab"
>
<v-badge
Expand All @@ -52,7 +51,6 @@
</v-badge>
</v-tab>
<v-tab
v-can:INVITE_MEMBERS.hide
data-test="invitations-tab"
>
Invitations
Expand Down
14 changes: 13 additions & 1 deletion auth-web/src/components/auth/common/ProductTOS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</div>
<v-checkbox
v-model="termsAccepted"
:disabled="canAcceptTerms"
color="primary"
class="terms-checkbox align-checkbox-label--top ma-0 pa-0"
hide-details
Expand Down Expand Up @@ -39,15 +40,25 @@

<script lang="ts">
import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator'
import { KCUserProfile } from 'sbc-common-components/src/models/KCUserProfile'
import { Role } from '@/util/constants'
import { mapState } from 'pinia'
import { useUserStore } from '@/stores/user'

@Component
@Component({
computed: {
...mapState(useUserStore, ['currentUser'])
}
})
export default class ProductTOS extends Vue {
@Prop({ default: '' }) userName: string
@Prop({ default: '' }) orgName: string
@Prop({ default: false }) isTOSAlreadyAccepted: boolean
@Prop({ default: false }) isApprovalFlow: boolean
termsAccepted: boolean = false
canAcceptTerms: boolean = false
public istosTouched: boolean = false
readonly currentUser!: KCUserProfile

@Watch('isTOSAlreadyAccepted')
onisTOSALreadyAcceptedChange (newTos:boolean, oldTos:boolean) {
Expand All @@ -57,6 +68,7 @@ export default class ProductTOS extends Vue {
}

public mounted () {
this.canAcceptTerms = this.currentUser?.roles?.includes(Role.ContactCentreStaff)
this.termsAccepted = this.isTOSAlreadyAccepted
}

Expand Down
13 changes: 10 additions & 3 deletions auth-web/src/components/auth/common/StaffAccountsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,10 @@
</v-btn>
</template>
<v-list>
<v-list-item @click="viewInBusinessRegistryDashboard(item)">
<v-list-item
v-if="canAccessBusinessRegistryDashboard"
@click="viewInBusinessRegistryDashboard(item)"
>
<v-list-item-subtitle>
<v-icon style="font-size: 14px">mdi-view-dashboard</v-icon>
<span class="pl-2">Business Registry Dashboard</span>
Expand All @@ -301,7 +304,8 @@
</template>

<script lang="ts">
import { AccessType, Account, AccountStatus, LoginSource, SessionStorageKeys } from '@/util/constants'
import { AccessType, Account, AccountStatus, LoginSource, Role, SessionStorageKeys } from '@/util/constants'

import {
DEFAULT_DATA_OPTIONS,
cachePageInfo,
Expand All @@ -328,6 +332,7 @@ import debounce from '@/util/debounce'
import { useI18n } from 'vue-i18n-composable'
import { useOrgStore } from '@/stores/org'
import { useStaffStore } from '@/stores/staff'
import { useUserStore } from '@/stores/user'

export default defineComponent({
name: 'StaffAccountsTable',
Expand All @@ -354,6 +359,7 @@ export default defineComponent({
const { t } = useI18n()
const orgStore = useOrgStore()
const staffStore = useStaffStore()
const { currentUser } = useUserStore()
const defaultHeaders = [
{ text: 'Account Name', value: 'name', visible: true },
{ text: 'Branch Name', value: 'branchName', visible: true },
Expand Down Expand Up @@ -430,7 +436,8 @@ export default defineComponent({
decisionMadeBy: '',
orgType: OrgAccountTypes.ALL,
statuses: [props.accountStatus]
} as OrgFilterParams
} as OrgFilterParams,
canAccessBusinessRegistryDashboard: computed(() => !currentUser?.roles?.includes(Role.ContactCentreStaff))
})

state.accountTypes = Array.from(Object.keys(state.accountTypeMap))
Expand Down
Loading
Loading