fix(acl): keep empty draft rules and clarify OR/AND hint

Empty rules were stripped on re-parse so Add rule looked broken; editor now keeps drafts until filled.
This commit is contained in:
2026-10-22 12:18:05 +03:30
parent 09a60b3b5a
commit 73c87b8be4
2 changed files with 30 additions and 9 deletions
+20 -4
View File
@@ -277,19 +277,28 @@ function addCustomSource(index: number) {
</label>
<label>
<input v-model="mode" type="radio" value="rules" :disabled="disabled" />
فقط با قوانین (چند قانون با OR)
محدود به قوانین زیر
</label>
</div>
<template v-if="mode === 'rules'">
<p class="hint">
قوانین با هم «یا» می‌شوند. داخل هر قانون، گزینه‌های پرشده با هم «و» هستند.
هر قانون یک راه جدا برای دیدن داده است. اگر چند قانون بگذارید، کافی است
<strong>یکی از آن‌ها</strong> برقرار باشد تا رکورد دیده شود.
داخل یک قانون، گزینه‌هایی که تیک می‌زنید باید
<strong>همه با هم</strong> برقرار باشند.
مثال: «پرونده‌های خودم» به‌عنوان قانون ۱ و «گروه VIP» به‌عنوان قانون ۲ → هم مال خودش را می‌بیند، هم VIP را.
</p>
<article v-for="(rule, index) in rules" :key="index" class="dae-rule">
<header>
<strong>قانون {{ index + 1 }}</strong>
<span class="muted">{{ ruleSummary(rule) }}</span>
<UiButton v-if="!disabled" variant="secondary" @click="removeRule(index)">
<UiButton
v-if="!disabled"
type="button"
variant="secondary"
@click.prevent="removeRule(index)"
>
حذف
</UiButton>
</header>
@@ -464,7 +473,14 @@ function addCustomSource(index: number) {
</fieldset>
</article>
<UiButton v-if="!disabled" variant="secondary" @click="addRule">+ قانون جدید</UiButton>
<UiButton
v-if="!disabled"
type="button"
variant="secondary"
@click.prevent="addRule"
>
+ قانون جدید
</UiButton>
</template>
<p v-else-if="!hasLimits" class="hint">
@@ -10,7 +10,6 @@ import {
DATA_ACCESS_SECTION_LABELS,
DATA_ACCESS_SECTIONS,
emptySectionDataAccess,
parseDataAccessPolicy,
} from '@mento/shared';
import { api } from '@/lib/api';
import { useCustomerGroups } from '@/lib/customer-groups';
@@ -57,15 +56,21 @@ watch(
{ immediate: true },
);
const policy = computed(() => parseDataAccessPolicy(props.modelValue));
/** بدون parse سخت‌گیرانه تا قانون خالیِ در حال ویرایش پاک نشود */
function sectionValue(key: DataAccessSection): SectionDataAccess {
return policy.value[key] ?? emptySectionDataAccess();
const raw = props.modelValue?.[key];
if (raw && typeof raw === 'object') {
return {
mode: raw.mode === 'rules' ? 'rules' : 'all',
rules: Array.isArray(raw.rules) ? raw.rules.map((r) => ({ ...r })) : [],
};
}
return emptySectionDataAccess();
}
function setSection(key: DataAccessSection, next: SectionDataAccess) {
emit('update:modelValue', {
...policy.value,
...props.modelValue,
[key]: next,
});
}