Files
hedena_gold/apps/admin-panel/src/stores/users.ts
T

115 lines
3.4 KiB
TypeScript

// 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;
},
},
});