refactor(resource): drop the branch domain from resources
Resources never needed a branch: devices and rooms belong to the clinic itself, and the picker always had exactly one option — a mandatory click that decided nothing. - `address_uuid` is now optional on resource and pool creation; when it is missing the environment's own address is used. Clients still sending it keep working. - The panel no longer asks for or displays a branch anywhere: resource form, list column and filter, pool form and column, detail row, and the resource-first booking page. - Availability no longer gates on `doctor_addresses.active`. That gate shut down every device of a clinic whose address row happened to be inactive, with a message no page in the panel could act on — no endpoint writes that column at all. `address_id` stays on the resource: the timezone and the tenant pair are derived from it. It is simply no longer the user's decision. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,6 @@ import SearchableSelect from '../components/ui/SearchableSelect';
|
||||
import { ActiveBadge } from '../components/ui/StatusBadge';
|
||||
import { useUrlState } from '../hooks/useUrlState';
|
||||
import { usePermissions } from '../hooks/usePermissions';
|
||||
import { useAddresses } from '../hooks/useAddresses';
|
||||
import { useResources, useResourceTypes, useSkills } from '../hooks/useResources';
|
||||
import ResourceFormModal from '../components/resources/ResourceFormModal';
|
||||
import type { ClinicResource } from '../types';
|
||||
@@ -29,17 +28,15 @@ const SUBJECT_LABEL: Record<string, string> = {
|
||||
*/
|
||||
export default function ResourcesPage() {
|
||||
const [urlState, setUrlState] = useUrlState({
|
||||
search: '', address: '', type: '', skill: '', status: '',
|
||||
search: '', type: '', skill: '', status: '',
|
||||
});
|
||||
|
||||
const { addresses } = useAddresses();
|
||||
const { types } = useResourceTypes();
|
||||
const { skills } = useSkills();
|
||||
const { can } = usePermissions();
|
||||
const canUpdate = can('appointment_settings', 'update');
|
||||
|
||||
const { resources, loading, create } = useResources({
|
||||
address_uuid: urlState.address || undefined,
|
||||
type_uuid: urlState.type || undefined,
|
||||
skill_uuid: urlState.skill || undefined,
|
||||
active: urlState.status || undefined,
|
||||
@@ -67,7 +64,6 @@ export default function ResourcesPage() {
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{ key: 'address_name', header: 'شعبه', render: (r) => <span style={{ fontSize: 13 }}>{r.address_name || '—'}</span> },
|
||||
{
|
||||
key: 'capacity',
|
||||
header: 'ظرفیت همزمان',
|
||||
@@ -127,16 +123,6 @@ export default function ResourcesPage() {
|
||||
emptyMessage="هیچ منبعی با این فیلترها یافت نشد"
|
||||
headerExtra={
|
||||
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginRight: 'auto' }}>
|
||||
<div style={{ minWidth: 180 }}>
|
||||
<SearchableSelect
|
||||
options={addresses.map((b) => ({ value: b.uuid, label: b.name || 'بدون نام' }))}
|
||||
value={urlState.address || null}
|
||||
onChange={(v) => setUrlState({ address: v ? String(v) : '' })}
|
||||
placeholder="همهٔ شعبهها"
|
||||
isClearable
|
||||
height={36}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ minWidth: 170 }}>
|
||||
<SearchableSelect
|
||||
options={types.map((t) => ({ value: t.uuid, label: t.name }))}
|
||||
@@ -185,7 +171,6 @@ export default function ResourcesPage() {
|
||||
<ResourceFormModal
|
||||
open={createOpen}
|
||||
resource={null}
|
||||
addresses={addresses}
|
||||
types={types}
|
||||
saving={create.isPending}
|
||||
onClose={() => setCreateOpen(false)}
|
||||
|
||||
Reference in New Issue
Block a user