mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-19 03:04:05 +00:00
Add super-admin Administration section and restructure global vs company settings
- Add Administration sidebar section (super-admin only) with Companies, Users, and Global Settings pages - Add super-admin middleware, controllers, and API routes under /api/v1/super-admin/ - Allow super-admins to manage all companies and users across tenants - Add user impersonation with short-lived tokens, audit logging, and UI banner - Move system-level settings (Mail, PDF, Backup, Update, File Disk) from per-company to Administration > Global Settings - Convert save_pdf_to_disk from CompanySetting to global Setting - Add per-company mail configuration overrides (optional, falls back to global) - Add CompanyMailConfigService to apply company mail config before sending emails
This commit is contained in:
162
resources/scripts/admin/stores/administration.js
vendored
Normal file
162
resources/scripts/admin/stores/administration.js
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
import http from '@/scripts/http'
|
||||
import Ls from '@/scripts/services/ls.js'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from '@/scripts/stores/notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useAdministrationStore = defineStore('administration', {
|
||||
state: () => ({
|
||||
companies: [],
|
||||
totalCompanies: 0,
|
||||
selectedCompany: null,
|
||||
|
||||
users: [],
|
||||
totalUsers: 0,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
fetchCompanies(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.get('/api/v1/super-admin/companies', { params })
|
||||
.then((response) => {
|
||||
this.companies = response.data.data
|
||||
this.totalCompanies = response.data.meta
|
||||
? response.data.meta.total
|
||||
: response.data.data.length
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCompany(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.get(`/api/v1/super-admin/companies/${id}`)
|
||||
.then((response) => {
|
||||
this.selectedCompany = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchUsers(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.get('/api/v1/super-admin/users', { params })
|
||||
.then((response) => {
|
||||
this.users = response.data.data
|
||||
this.totalUsers = response.data.meta
|
||||
? response.data.meta.total
|
||||
: response.data.data.length
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchUser(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.get(`/api/v1/super-admin/users/${id}`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateUser(id, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.put(`/api/v1/super-admin/users/${id}`, data)
|
||||
.then((response) => {
|
||||
const { global } = window.i18n
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('administration.users.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
impersonateUser(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.post(`/api/v1/super-admin/users/${id}/impersonate`)
|
||||
.then((response) => {
|
||||
Ls.set('admin.impersonating', 'true')
|
||||
Ls.set('auth.token', `Bearer ${response.data.token}`)
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
stopImpersonating() {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.post('/api/v1/super-admin/stop-impersonating')
|
||||
.then((response) => {
|
||||
Ls.remove('admin.impersonating')
|
||||
Ls.remove('auth.token')
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
Ls.remove('admin.impersonating')
|
||||
Ls.remove('auth.token')
|
||||
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCompany(id, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.put(`/api/v1/super-admin/companies/${id}`, data)
|
||||
.then((response) => {
|
||||
const { global } = window.i18n
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'administration.companies.updated_message'
|
||||
),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user