admin-panel: convert wholesale-customer add form into a modal

bulkCustomer.vue (reached today only via /customer/add's AddCustomer.vue tab
wrapper, and via /bulkCustomer/edit/:id from 5 different list variants) gets
open/id modal support; both routes stay as a fallback.

OmdeCustomerList.vue is shared by 5 list pages (OmdeList, BankerList,
ShopkeeperList, OmdeNonVerifiedList, OmdeArchivedList). Per user decision, the
add button and modal-based edit are wired only on OmdeList.vue (the one this
form conceptually belongs to) via a new showAddButton prop, default false —
the other four keep navigating to the edit route unchanged.

singleCustomer.vue and ReagentCustomer.vue were also planned as add-form
candidates but have no create entry point anywhere in the app (edit-only,
reachable solely via /singleCustomer/edit/:id and /reagent/edit/:id) — left
untouched, nothing to convert. offersIgnore-add-edit.vue is a standalone
settings page with no list counterpart, not a create form — left as a page.

Verified: pnpm build passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-09-14 17:05:42 +03:30
co-authored by Claude Sonnet 5
parent 1bb9802d1f
commit 0e1dd0c36a
3 changed files with 169 additions and 7 deletions
@@ -13,6 +13,13 @@
-->
<div id="page-user-list">
<a-card :title="title">
<ListPageHeader
v-if="showAddButton"
rid="persons.create.client"
add-label="افزودن مشتری عمده"
@add="openAdd"
/>
<div v-if="query && query.count && query.total">
{{ query.total }} رکورد یافت شد -
<span class="text-danger">{{ query.count }} رکورد غیر فعال</span>
@@ -205,6 +212,15 @@
</div>
</template>
</XTable>
<BulkCustomer
v-if="showAddButton"
:key="editingId ?? 'new'"
:open="modalOpen"
:id="editingId"
@update:open="modalOpen = $event"
@success="tbl?.fetch()"
/>
</a-card>
</div>
</template>
@@ -226,6 +242,8 @@ import {
UnorderedListOutlined,
} from '@ant-design/icons-vue';
import XTable from '../../../components/x-table/XTable.vue';
import ListPageHeader from '../../../components/common/ListPageHeader.vue';
import BulkCustomer from '../../apps/customer/bulkCustomer.vue';
import { useUsersStore } from '../../../stores/users';
import api from '../../../api/client';
import type { XTbl } from '../../../components/x-table/model';
@@ -243,8 +261,10 @@ const props = withDefaults(
* silently "fixed" — see docs/ADMIN-PORT-PLAN.md.
*/
rejectOnlyStepOne?: boolean;
/** Only OmdeList.vue passes this — see the comment on its call site. */
showAddButton?: boolean;
}>(),
{ rejectOnlyStepOne: false },
{ rejectOnlyStepOne: false, showAddButton: false },
);
const router = useRouter();
@@ -252,6 +272,8 @@ const users = useUsersStore();
const hasPermission = (rid: string) => Boolean(users.hasPermission(rid));
const tbl = ref<{ fetch: () => Promise<void> } | null>(null);
const modalOpen = ref(false);
const editingId = ref<string | undefined>(undefined);
const query = ref<{ count?: number; total?: number } | undefined>(undefined);
/** legacy setCount(): the "N رکورد غیر فعال" banner above the grid */
@@ -399,7 +421,20 @@ async function toggleArchive(id: string) {
}
function toEdit(id: string) {
router.push(`/bulkCustomer/edit/${id}`);
// Only the OmdeList variant (showAddButton) has the modal wired up; the
// other four (BankerList, ShopkeeperList, OmdeNonVerifiedList,
// OmdeArchivedList) keep navigating to the route, unchanged.
if (props.showAddButton) {
editingId.value = id;
modalOpen.value = true;
} else {
router.push(`/bulkCustomer/edit/${id}`);
}
}
function openAdd() {
editingId.value = undefined;
modalOpen.value = true;
}
function toView(id: string) {
router.push(`/bulkCustomer/view/${id}`);
@@ -1,6 +1,10 @@
<template>
<!-- Ported from legacy views/customer/omde/OmdeList.vue (615 lines). -->
<OmdeCustomerList :title="title" :model="model" />
<!--
Ported from legacy views/customer/omde/OmdeList.vue (615 lines).
The only one of OmdeCustomerList's five callers with an add button — see
OmdeCustomerList.vue's showAddButton prop for why it isn't on all five.
-->
<OmdeCustomerList :title="title" :model="model" show-add-button />
</template>
<script setup lang="ts">