fix(ui): act-as strip no longer covers headers; customer type and slider permission

- apps: the fixed «در حال مشاهده به‌عنوان» strip (38px) sat over the fixed page
  headers, which still sat at top: 0 (the old 30px body padding was shorter than
  the strip too). The strip's height is now one variable, --aab-h, that the
  fixed headers (PageBar, home, dashboard, toasts) use as their top.
- admin: the customer form offers only «مغازه دار اپلیکیشن» to anyone but the
  super admin; bankers and walk-in shopkeepers are listed by super-admin-only
  endpoints, so ordinary admins lost the customers they created under them.
- admin: the mobile slider rid (custom.config.statics.slider) was only under the
  «سفارشی» branch, which the permission screen hides outside level 104. Same rid,
  now listed under «مدیریت ثابت ها». Display only: the slider routes are still
  gated by config.statics.

Rebuilds admin-panel, user-app and user-app-v2 dist.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mahmood
2026-10-26 11:16:23 +03:30
co-authored by Claude Sonnet 5.5
parent 8c4ca20a25
commit 5ddb225813
240 changed files with 257 additions and 235 deletions
@@ -66,7 +66,7 @@
:filter-option="filterUserType"
style="width: 100%; direction: rtl !important"
>
<a-select-option v-for="item in userTypes" :key="item.id" :value="item.id">
<a-select-option v-for="item in userTypeOptions" :key="item.id" :value="item.id">
{{ item.title }}
</a-select-option>
</a-select>
@@ -198,7 +198,7 @@
:filter-option="filterUserType"
style="width: 100%; direction: rtl !important"
>
<a-select-option v-for="item in userTypes" :key="item.id" :value="item.id">
<a-select-option v-for="item in userTypeOptions" :key="item.id" :value="item.id">
{{ item.title }}
</a-select-option>
</a-select>
@@ -299,7 +299,7 @@
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { message } from 'ant-design-vue';
import {
@@ -316,6 +316,7 @@ import {
import BaseFormModal from '../../../components/common/BaseFormModal.vue';
import ImageUploadInput from '../../../components/upload/ImageUploadInput.vue';
import api from '../../../api/client';
import { useUsersStore } from '../../../stores/users';
import CityTreeSelect from '../../../components/common/CityTreeSelect.vue';
import DateInput from '../../../components/input/DateInput.vue';
@@ -333,6 +334,7 @@ const asModal = props.asModal === true;
const route = useRoute();
const router = useRouter();
const users = useUsersStore();
const id = asModal ? props.id : (route.params.id as string | undefined);
const loading = ref(false);
@@ -367,6 +369,16 @@ const userTypes = [
{ id: 4, title: 'بنکدار' },
];
// Bankers and walk-in shopkeepers are listed by super-admin-only endpoints, so a
// customer an ordinary admin files under them would vanish from every list they
// can open. Everyone else is offered the app shopkeeper only (plus whatever type
// an existing customer already has, so editing one never blanks the select).
const userTypeOptions = computed(() =>
users.isSuperAdmin
? userTypes
: userTypes.filter((t) => t.id === 2 || t.id === Number(form.type)),
);
function filterUserType(input: string, option: any) {
return String(option?.children?.[0]?.children ?? '').includes(input);
}
@@ -827,7 +827,11 @@ export const treeData: PermissionNode[] = [
"key": "config.statics.tags.remove"
},
]
}
},
{
"title": "اسلایدر موبایل",
"key": "custom.config.statics.slider"
},
]
},
{
@@ -860,10 +864,6 @@ export const treeData: PermissionNode[] = [
"title": "سفارشی",
"key": "custom",
"children": [
{
"title": "اسلایدر موبایل",
"key": "custom.config.statics.slider"
},
{
"title": "برچسب بنر اول سایت",
"key": "custom.config.statics.tags.banner.ids"