feat(roles): let each section decide who may assign work to others
Section access now only creates a record for yourself. Assigning it to a colleague requires a separate permission on that section. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import type {
|
||||
ActivityChecklistItem,
|
||||
ActivityFieldDef,
|
||||
@@ -11,6 +11,8 @@ import type {
|
||||
PersonDto,
|
||||
} from '@mento/shared';
|
||||
import { api } from '@/lib/api';
|
||||
import { canAssignToOthers } from '@/lib/assign-access';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { toFaDigits } from '@/lib/jalali';
|
||||
import JalaliDateInput from '@/components/JalaliDateInput.vue';
|
||||
import UserMultiSelect from '@/components/UserMultiSelect.vue';
|
||||
@@ -22,6 +24,8 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const model = defineModel<ActivityFieldValues>({ required: true });
|
||||
const auth = useAuthStore();
|
||||
const canAssignOthers = computed(() => canAssignToOthers(auth.user, 'activities'));
|
||||
|
||||
function get<T extends ActivityFieldValue>(key: string, fallback: T): T {
|
||||
const v = model.value[key];
|
||||
@@ -304,6 +308,7 @@ watch(
|
||||
<UserMultiSelect
|
||||
:model-value="participants(f.key).userIds"
|
||||
:users="users"
|
||||
:disabled="!canAssignOthers"
|
||||
add-label="افزودن همکار"
|
||||
empty-label="همکاری انتخاب نشده"
|
||||
@update:model-value="(ids: string[]) => patchParticipants(f.key, { userIds: ids })"
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
todayKey,
|
||||
} from '@/lib/routines';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { canAssignToOthers } from '@/lib/assign-access';
|
||||
|
||||
const { Text: ATypographyText } = Typography;
|
||||
|
||||
@@ -117,7 +118,7 @@ watch(
|
||||
|
||||
const assignees = computed(() => {
|
||||
const c = ctx.value;
|
||||
if (!c?.isManager) return [];
|
||||
if (!c?.isManager || !canAssignToOthers(auth.user, 'routines')) return [];
|
||||
return c.users;
|
||||
});
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
UiTextarea,
|
||||
} from '@/components/ui';
|
||||
import { api } from '@/lib/api';
|
||||
import { canAssignToOthers } from '@/lib/assign-access';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { formatJalaliDayClock } from '@/lib/jalali';
|
||||
import {
|
||||
ENTITY_TYPE_LABELS,
|
||||
@@ -103,7 +105,9 @@ const customerTask = computed(() => {
|
||||
return (t.source !== 'routine' && t.source !== 'manual') || t.entities.length > 0;
|
||||
});
|
||||
const done = computed(() => task.value?.status === 'completed');
|
||||
const auth = useAuthStore();
|
||||
const canManage = computed(() => !!shell?.context.value?.isManager);
|
||||
const canAssignOthers = computed(() => canAssignToOthers(auth.user, 'routines'));
|
||||
const priorities = Object.entries(PRIORITY_LABELS) as Array<[ActivityPriority, string]>;
|
||||
|
||||
function startEdit() {
|
||||
@@ -276,7 +280,7 @@ function eventText(ev: RoutineTaskEventDto): string {
|
||||
<JalaliDateInput v-model="edit.time" mode="time" />
|
||||
</UiField>
|
||||
</template>
|
||||
<UiField v-if="canManage" label="مسئول" class="span-2">
|
||||
<UiField v-if="canManage && canAssignOthers" label="مسئول" class="span-2">
|
||||
<UiSelect v-model="edit.assigneeId">
|
||||
<option v-for="u in shell?.context.value?.users ?? []" :key="u.id" :value="u.id">
|
||||
{{ u.fullName }}
|
||||
|
||||
Reference in New Issue
Block a user