New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@agendize/vue-agendize

Package Overview
Dependencies
Maintainers
7
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agendize/vue-agendize - npm Package Compare versions

Comparing version 1.17.0 to 1.18.0

src/presentation/view/dashboard/View.vue

8

CHANGELOG.md
# Changelog
## [1.18.0] - 11-12-2023
### Ajout
- Ajout de la gestion des status custom
- Ajout de messages d'erreurs, spécifiques aux borne min et max, sur la durée de création et la capacité d'un événement, ainsi que sur la durée d'un service et son délai d'annulation
- Revision system de droit et possibilité de se loggué sans droit scheduling
### Modification
- Ajout des traductions explicite LastName pour la langue EN
## [1.17.0] - 28-11-2023

@@ -4,0 +12,0 @@ ### Ajout

2

package.json
{
"name": "@agendize/vue-agendize",
"private": false,
"version": "1.17.0",
"version": "1.18.0",
"description": "Vue agendize application",

@@ -6,0 +6,0 @@ "keywords": [

@@ -5,14 +5,16 @@ import {appInitialState, AppState, LoadedState, LoadingState, OrganisationSelectionState} from "./AppState";

AccountEntity,
AclEntity,
ApiErrors,
BrowserStorage,
CalendarApi,
CompanyEntity,
UserEntity,
BrowserStorage,
StorageKeys, AclEntity
StorageKeys,
UserEntity
} from "@agendize/js-calendar-api";
import {Locale,initTranslationTool} from "@agendize/az-i18n";
import {initTranslationTool, Locale} from "@agendize/az-i18n";
import {identifyUser as identifyUserForMatomo} from "./services/matomo";
import {getUserLocale} from "./utils/accountUtils";
import {goToAuthorizedRoute} from "./router";
import {RouteLocationNormalizedLoaded} from "vue-router";
import {getAuthorizedRouteName, ROUTE_NAMES} from "./router";
import {Router} from "vue-router";
import {Acl, useAcl} from "@agendize/vue-acl";

@@ -23,3 +25,2 @@ const MATOMO_HOST = 'https://analytics.rdv.az/js'

private api: CalendarApi
private acl: any
private fontAwesomeKitId: string

@@ -29,10 +30,11 @@ private weglotApiKey: string

private stonlyWid: string
private account?: AccountEntity
private route: RouteLocationNormalizedLoaded
private router: Router
constructor(api: CalendarApi, acl: any, fontAwesomeKitId: string, weglotApiKey: string, matomoCode: string, stonlyWid: string, route: RouteLocationNormalizedLoaded) {
private acl: Acl = useAcl()
private accountStore = useAccountStore()
constructor(api: CalendarApi, fontAwesomeKitId: string, weglotApiKey: string, matomoCode: string, stonlyWid: string, router: Router) {
super(appInitialState);
this.api = api
this.acl = acl
this.fontAwesomeKitId = fontAwesomeKitId

@@ -42,3 +44,3 @@ this.weglotApiKey = weglotApiKey

this.stonlyWid = stonlyWid
this.route = route
this.router = router
}

@@ -74,8 +76,7 @@

load() {
const accountStore = useAccountStore()
accountStore.fetchAccount(true, (account: AccountEntity) => {
this.account = account
this.accountStore.fetchAccount(true, (account: AccountEntity) => {
this.initStorage(account)
const organisationSession = sessionStorage.getItem("organisation")
const browserStorage = new BrowserStorage()
const organisationSession = browserStorage.getItem(StorageKeys.ORGANISATION)
if (organisationSession) {

@@ -102,4 +103,3 @@ this.organisationSelected(JSON.parse(organisationSession))

switchOrganisation(backToPreviousAccount: boolean) {
const accountStore = useAccountStore()
this.changeState(new OrganisationSelectionState(accountStore.account.acls?.filter(acl => acl.active) ?? [], backToPreviousAccount))
this.changeState(new OrganisationSelectionState(this.accountStore.account.acls?.filter((acl: AclEntity) => acl.active) ?? [], backToPreviousAccount))
}

@@ -112,3 +112,26 @@

organisationSelected(organisation: AccountEntity) {
this._fetchAllUsers(organisation)
const acl = useAcl()
const organisationAcl: AclEntity | undefined = this.accountStore.account?.acls?.find((acl: AclEntity) => acl.organisationId === organisation.id) as AclEntity
this.api.refreshOrganisationStorage(organisation)
if (organisationAcl) {
acl.init(organisationAcl).then(() => {
const currentRoute = this.router.currentRoute.value
const landingPage = getAuthorizedRouteName(currentRoute)
if (landingPage) {
if (landingPage === ROUTE_NAMES.NOT_FOUND) {
this.changeState(new LoadedState(organisation, undefined))
} else if (landingPage === ROUTE_NAMES.CALENDAR || landingPage === 'calendar') {
this._initScheduling(organisation)
} else {
this.router.push({name: landingPage}).then(() => {
this.changeState(new LoadedState(organisation, undefined))
})
}
} else {
this.loginError(ApiErrors.INSUFFICIENT_RIGHT)
}
})
} else {
this.loginError(ApiErrors.INSUFFICIENT_RIGHT)
}
}

@@ -130,4 +153,2 @@

private selectOrganisation(aclAccounts?: AclEntity[]) {
if (!aclAccounts || aclAccounts.length === 0) {

@@ -137,5 +158,5 @@ // Ne devrais pas arriver car l'authentification est en succés uniquement si au moins un compte est actif

} else if (aclAccounts.length === 1) {
this.api.getAccount(aclAccounts[0].account).then(organisationAccount => {
if (organisationAccount && organisationAccount.result) {
this._fetchAllUsers(organisationAccount.result)
this.api.getAccount(aclAccounts[0].organisation).then(response => {
if (response && response.result) {
this.organisationSelected(response.result)
}

@@ -211,17 +232,20 @@ })

private _fetchAllUsers(organisation: AccountEntity) {
private _initScheduling(organisation: AccountEntity) {
//TODO voir si c'est encore pertinent de faire un fetch all pour n'avoir que l'utilisateur connecté
//Le volume est réduit avec le getDefault plutôt que getAll
const accountStore = useAccountStore()
this.api.getUserById(organisation.email!, accountStore.account.id).then((response: { result: UserEntity | undefined, local: boolean }) => {
this.api.getUserById(organisation.email!, this.accountStore.account.id).then((response: { result: UserEntity | undefined, local: boolean }) => {
if (response) {
let meInOrganisation = response.result
if (meInOrganisation) {
//Pour le moment ça marche plus trop pour remplir StorageKeys.AGENDA_USERS par ce biais
this.api.refreshUserSession(organisation, undefined, meInOrganisation)
this.api.refreshUserStorage(undefined, meInOrganisation)
identifyUserForMatomo(meInOrganisation.login!)
identifyUserForMatomo(meInOrganisation)
this._fetchAllCompanies(organisation, meInOrganisation)
this.api.getAllCompanies(organisation.email).then((companiesResponse: { results: CompanyEntity[] | undefined }) => {
this.router.push({name: ROUTE_NAMES.CALENDAR}).then(() => {
this.changeState(new LoadedState(organisation, meInOrganisation))
})
}).catch(() => {
this.loginError(ApiErrors.INTERNAL_ERROR)
})
} else {

@@ -237,29 +261,2 @@ this.loginError(ApiErrors.INTERNAL_ERROR)

}
private _fetchAllCompanies(organisation: AccountEntity, meInOrganisation: UserEntity) {
this.api.getAllCompanies(organisation.email).then((companiesResponse: { results: CompanyEntity[] | undefined }) => {
this._initAcl(organisation, meInOrganisation, companiesResponse.results)
}).catch(() => {
this.loginError(ApiErrors.INTERNAL_ERROR)
})
}
private _initAcl(organisation: AccountEntity, meInOrganisation: UserEntity, companies?: CompanyEntity[]) {
const initialAbilityAccount = new Map<{ objectType: any, objectId: string }, string>();
if (companies) {
companies.forEach(company => {
initialAbilityAccount.set({
objectType: 'company',
objectId: company.id!
}, company.owner?.userName)
})
}
const accountStore = useAccountStore()
this.acl.init(this.api, accountStore.account?.acls?.find((acl: any) => acl.account === organisation.email), meInOrganisation).then(() => {
goToAuthorizedRoute(accountStore, this.route).then(() => {
this.changeState(new LoadedState(organisation, meInOrganisation))
})
})
}
}

@@ -63,6 +63,6 @@ import {ConsoleLogger, LoggerLevel} from '@agendize/js-calendar-api'

const acl = createAcl({logger: logger, router: appRouter, onDeniedRoute: '/404'});
const acl = createAcl({api, logger})
app.use(acl)
const store = createStore(api, useAcl())
const store = createStore(api)
app.use(store)

@@ -69,0 +69,0 @@

import {
createRouter,
createWebHistory, NavigationFailure, RouteLocationNamedRaw, RouteLocationNormalized,
createWebHistory, NavigationFailure, RouteLocationMatched, RouteLocationNamedRaw, RouteLocationNormalized,
RouteLocationNormalizedLoaded, RouteLocationPathRaw, RouteLocationRaw, Router, RouteRecordName,

@@ -17,2 +17,4 @@ RouteRecordRaw,

import {getEnvConfig} from "../utils/config";
import {useAccountStore} from "@agendize/vue-tools";
import {AclAbility, AclRole} from "@agendize/vue-acl";

@@ -23,2 +25,3 @@ const i18n = locales('fr')

LOGIN = 'login',
DASHBOARD = 'agendize-dashboard',
CALENDAR = 'agendize-calendar',

@@ -38,2 +41,3 @@ FORMS = 'agendize-forms',

export const enum ROUTE_PATH {
DASHBOARD = '/dashboard',
CALENDAR = '/calendar',

@@ -63,2 +67,3 @@ FORMS = '/forms',

title: i18n.global.t('agendize.router-meta.calendar.title'),
canAny: ['readAppointment', 'readStaffAppointment'],
icon: {

@@ -80,2 +85,25 @@ name: 'far fa-calendar'

{
path: ROUTE_PATH.DASHBOARD,
name: ROUTE_NAMES.DASHBOARD,
component: () => import('../presentation/view/dashboard/View.vue'),
meta: {
title: i18n.global.t('agendize.router-meta.dashboard.title'),
canNone: ['readAppointment', 'readStaffAppointment'],
canCount: { abilities: ['readForm', 'readQueue', 'readClient', 'readReport'], count: 2 },
icon: {
name: 'far fa-objects-column'
},
description: i18n.global.t('agendize.router-meta.dashboard.description'),
requiresAuth: true,
leftSidebar: true,
topBar: true,
alert: false,
primary: true,
displayMobile: true,
burgerAriaLabel: i18n.global.t('agendize.router-meta.dashboard.menuDescription'),
burgerPopoverTitle: i18n.global.t('agendize.router-meta.dashboard.menu'),
burgerPopoverDescription: i18n.global.t('agendize.router-meta.dashboard.menuDescription'),
}
},
{
path: ROUTE_PATH.WORKING_PLANNING,

@@ -323,3 +351,4 @@ name: ROUTE_NAMES.WORKING_PLANNING,

await api.getAccessToken(to.query.code.toString())
next({name: ROUTE_NAMES.CALENDAR})
const routeName = getLandingPageRouteName()
next({name: routeName})
} catch (e: any) {

@@ -343,4 +372,14 @@ let errorCode

}
setTitle(to.meta?.title as (string | undefined))
next()
//@ts-ignore
const isItABackButton = window.popStateDetected
//@ts-ignore
window.popStateDetected = false
if (isItABackButton && !isRouteAuthorized(to)) {
next({ name: ROUTE_NAMES.NOT_FOUND})
} else {
setTitle(to.meta?.title as (string | undefined))
next()
}
})

@@ -456,4 +495,5 @@

export async function getIconifiedAuthorizedRoutes(accountStore: any, mobile: boolean) {
const abilityFunc = async (route: RouteRecordRaw) => {
export function getIconifiedAuthorizedRoutes(accountStore: any, mobile: boolean) {
const routeIsAccessible = (route: RouteRecordRaw) => {
// Check can ability
let abilityToCheck = route.meta?.can

@@ -463,11 +503,34 @@ if (abilityToCheck === undefined) {

}
if (abilityToCheck !== undefined && !accountStore.hasAbility(abilityToCheck)) {
return false
}
let can = (abilityToCheck === undefined || await accountStore.hasAbility(abilityToCheck) === true)
if (can) {
let roleToCheck = route.meta?.role ?? route.meta?.roleAny
if (roleToCheck !== undefined) {
can = await accountStore.hasAnyRoles(roleToCheck)
// Check canAny ability
abilityToCheck = route.meta?.canAny
if (abilityToCheck !== undefined && !accountStore.hasAnyAbility(abilityToCheck)) {
return false
}
// Check canNone ability
abilityToCheck = route.meta?.canNone
if (abilityToCheck !== undefined && accountStore.hasAnyAbility(abilityToCheck)) {
return false
}
// Check canCount ability
const routeAbilities: { abilities: AclAbility[], count: number } | undefined = route.meta?.canCount as { abilities: AclAbility[], count: number }
const abilitiesToCheck: AclAbility[] = routeAbilities?.abilities
const count = routeAbilities?.count
if (abilityToCheck !== undefined && count != undefined && abilitiesToCheck.filter(ability => accountStore.hasAbility(ability)).length < count) {
return false
}
// Check role
let roleToCheck = route.meta?.role ?? route.meta?.roleAny
if (roleToCheck !== undefined) {
if (!accountStore.hasAnyRoles(roleToCheck)) {
return false
}
}
return can
return true
}

@@ -480,4 +543,3 @@

const filterMap = await Promise.all(allAccessibleRoutes?.map(abilityFunc)??[]);
return allAccessibleRoutes?.filter((route, index) => filterMap[index])??[]
return allAccessibleRoutes?.filter(route => routeIsAccessible(route)) ?? []
}

@@ -499,34 +561,84 @@

// TODO lorsque le temps le permettra faire des router.push plutot que des redirects (useRouter() ne fonctionne pas pour le moment)
export async function goToAuthorizedRoute(accountStore: any, currentRoute: RouteLocationNormalizedLoaded) {
if (currentRoute.meta?.can || currentRoute.meta?.roleAny) {
if (currentRoute.name === undefined) {
window.location.assign('/')
return Promise.reject()
function isRouteAuthorized(route: RouteLocationNormalized) {
const accountStore = useAccountStore()
let meta = route.meta
let name = route.name
if (meta?.can || meta?.roleAny || meta?.canAny) {
if (name === undefined) {
return false
} else if (meta?.can instanceof Function) {
return meta.can(route)
} else {
const hasAbility = currentRoute.meta?.can ? await accountStore.hasAbility(currentRoute.meta?.can) : true
const hasRole = currentRoute.meta?.roleAny ? await accountStore.hasAnyRoles(currentRoute.meta?.roleAny) : true
if (!hasAbility || !hasRole) {
const to = notAuthorizedRouteRedirections.filter(r => r.from === currentRoute.name)[0]
if (to) {
window.location.assign(to.to)
return Promise.reject()
} else {
window.location.assign('/')
return Promise.reject()
}
const hasAbility = meta?.can ? accountStore.hasAbility(meta?.can as AclAbility) : true
const hasRole = meta?.roleAny ? accountStore.hasAnyRoles(meta?.roleAny as AclRole[]) : true
const hasAnyAbility = meta?.canAny ? accountStore.hasAnyAbility(meta?.canAny as AclAbility[]) : true
if (!hasAbility || !hasRole || !hasAnyAbility) {
return false
} else {
const to = baseRedirection.filter(r => r.from === currentRoute.name)[0]
if (to) {
window.location.assign(to.to)
return Promise.reject()
} else {
return Promise.resolve()
}
return true
}
}
} else {
if (name === undefined) {
return false
} else {
return true
}
}
return Promise.resolve()
}
export function getAuthorizedRouteName(currentRoute: RouteLocationNormalizedLoaded) {
const landingPage = getLandingPageRouteName()
if ((currentRoute.name === ROUTE_NAMES.DASHBOARD || currentRoute.matched[0]?.name === ROUTE_NAMES.DASHBOARD) && landingPage !== ROUTE_NAMES.DASHBOARD) {
return landingPage
}
if (isRouteAuthorized(currentRoute)) {
return currentRoute.name
} else {
return landingPage
}
}
export function getLandingPageRouteName() {
const accountStore = useAccountStore()
const hasScheduling = accountStore.hasAnyAbility(['readAppointment', 'readStaffAppointment'])
if (hasScheduling) {
return ROUTE_NAMES.CALENDAR
}
const hasForm = accountStore.hasAbility('readForm')
const hasQueue = accountStore.hasAbility('readQueue')
const hasCrm = accountStore.hasAbility('readClient')
const hasReport = accountStore.hasAbility('readReport')
const abilityWithoutSchedulingCount = [hasForm, hasQueue, hasCrm, hasReport].filter(ability => ability === true).length
if (abilityWithoutSchedulingCount === 0) {
return undefined
} else if (abilityWithoutSchedulingCount > 1) {
return ROUTE_NAMES.DASHBOARD
} else {
if (hasForm) {
return ROUTE_NAMES.FORMS
} else if (hasQueue) {
return ROUTE_NAMES.QUEUES
} else if (hasReport) {
return ROUTE_NAMES.REPORT
} else if (hasCrm) {
return ROUTE_NAMES.CRM
}
}
return ROUTE_NAMES.DASHBOARD
}
//@ts-ignore
window.popStateDetected = false
window.addEventListener('popstate', () => {
//@ts-ignore
window.popStateDetected = true
})
export default router

@@ -38,6 +38,6 @@ import {UserEntity} from "@agendize/js-calendar-api";

function identifyUser(user: UserEntity) {
window.Piwik?.getTracker().setUserId(user.login)
function identifyUser(userEmail: string) {
window.Piwik?.getTracker().setUserId(userEmail)
}
export {buildMatomoConfig, identifyUser}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc