feat: complete admin panel and backend admin api migration
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
// Ported from legacy henza_admin/src/store/users/index.js
|
||||
import { defineStore } from 'pinia';
|
||||
import api from '../api/client';
|
||||
|
||||
/**
|
||||
* Ported VERBATIM in behaviour from legacy store/users/index.js:3-9.
|
||||
*
|
||||
* getParents(['a','b','c']) -> ['a.b', 'a']
|
||||
*/
|
||||
function getParents(keys: string[]): string[] {
|
||||
const work = [...keys];
|
||||
const parents: string[] = [];
|
||||
while (work.length > 1) {
|
||||
work.pop();
|
||||
parents.push(work.join('.'));
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ported from legacy store/users/index.js:10-22.
|
||||
*
|
||||
* Granting "persons.list.client.omde" implicitly grants "persons.list.client",
|
||||
* "persons.list" and "persons", which is what keeps parent menu nodes visible.
|
||||
*
|
||||
* The legacy version assigned to a module-scoped `let rid` and relied on that
|
||||
* outer variable inside the .map() callback. This version is pure — identical
|
||||
* output, but no state leaking between calls (legacy's `rid` survived logout).
|
||||
*
|
||||
* NOTE it only walks UP; a rid never implies its children. That is why a user
|
||||
* granted "wallet" still cannot see the nav item guarded by "wallet.list" —
|
||||
* a legacy bug, preserved deliberately. See docs/ADMIN-PORT-PLAN.md.
|
||||
*/
|
||||
export function checkParent(values: string[]): string[] {
|
||||
let rid: string[] = [...values];
|
||||
values.forEach((x) => {
|
||||
const keys = x.split('.');
|
||||
if (keys.length > 1) {
|
||||
rid = [...new Set([...rid, ...getParents(keys)])];
|
||||
}
|
||||
});
|
||||
return rid;
|
||||
}
|
||||
|
||||
export interface UserInfo {
|
||||
id?: string;
|
||||
name?: string;
|
||||
fullName?: string;
|
||||
/**
|
||||
* Legacy split names into fname/lname. The schema stores one fullName, but the
|
||||
* API returns both keys so ported templates binding either keep working.
|
||||
*/
|
||||
fname?: string;
|
||||
lname?: string;
|
||||
mobile?: string;
|
||||
role?: string;
|
||||
ut?: number | null;
|
||||
branch_id?: string | null;
|
||||
user_type?: { id: number; title: string } | null;
|
||||
}
|
||||
|
||||
export const useUsersStore = defineStore('users', {
|
||||
state: () => ({
|
||||
// legacy: cityFilters — id -> title map used by table filters
|
||||
cityFilters: {} as Record<string | number, string>,
|
||||
userInfo: undefined as UserInfo | undefined,
|
||||
// undefined = "not fetched yet" (distinct from [] = "fetched, has none").
|
||||
// The router guard relies on that distinction, as legacy's did.
|
||||
roles: undefined as string[] | undefined,
|
||||
}),
|
||||
getters: {
|
||||
/**
|
||||
* Port of the global `Vue.prototype.$hasPermission` from legacy main.js.
|
||||
* Returns undefined when roles have not loaded — legacy did the same, which
|
||||
* renders as falsy in v-if.
|
||||
*/
|
||||
hasPermission: (state) => (permissionId: string) => {
|
||||
const roles = state.roles;
|
||||
if (roles) {
|
||||
return roles.includes(permissionId);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// legacy mutation setCities: builds an id -> title lookup
|
||||
setCities(payload: { id: string | number; title: string }[]) {
|
||||
payload.forEach((x) => {
|
||||
this.cityFilters[x.id] = x.title;
|
||||
});
|
||||
},
|
||||
async getCities() {
|
||||
try {
|
||||
const res = await api.post('cities/list');
|
||||
this.setCities(res.data.rows);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
setUserInfo(payload: UserInfo) {
|
||||
this.userInfo = payload;
|
||||
},
|
||||
deleteUserInfo() {
|
||||
this.userInfo = {};
|
||||
},
|
||||
/** legacy action getRoles: commits checkParent(roles), never the raw list. */
|
||||
getRoles(roles: string[]) {
|
||||
this.roles = checkParent(roles);
|
||||
},
|
||||
deleteRoles() {
|
||||
this.roles = undefined;
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user