|
|
@@ -13,7 +13,20 @@
|
|
|
/>
|
|
|
|
|
|
<div class="row full-width q-mt-md q-col-gutter-sm">
|
|
|
+ <div class="col-12">
|
|
|
+ <q-btn-toggle
|
|
|
+ v-model="form.access_scope"
|
|
|
+ spread
|
|
|
+ no-caps
|
|
|
+ toggle-color="primary"
|
|
|
+ :options="[
|
|
|
+ { label: 'Acesso de unidade', value: 'unit' },
|
|
|
+ { label: 'Acesso franqueadora', value: 'franchisor' },
|
|
|
+ ]"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
<StateSelect
|
|
|
+ v-if="form.access_scope === 'unit'"
|
|
|
v-model="form.state"
|
|
|
class="col-3"
|
|
|
outlined
|
|
|
@@ -22,6 +35,7 @@
|
|
|
/>
|
|
|
|
|
|
<UnitMultiSelect
|
|
|
+ v-if="form.access_scope === 'unit'"
|
|
|
v-model="form.units"
|
|
|
class="col-9"
|
|
|
outlined
|
|
|
@@ -30,7 +44,9 @@
|
|
|
/>
|
|
|
|
|
|
<UserTypeSelect
|
|
|
+ :key="form.access_scope"
|
|
|
v-model="form.user_type"
|
|
|
+ :access-scope="form.access_scope"
|
|
|
class="col-6"
|
|
|
outlined
|
|
|
label="Tipo de Usuário"
|
|
|
@@ -145,7 +161,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, computed, onMounted } from "vue";
|
|
|
+import { ref, computed, onMounted, watch } from "vue";
|
|
|
import { useRouter, useRoute } from "vue-router";
|
|
|
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
|
import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
@@ -170,10 +186,12 @@ const showPasswordConfirm = ref(false);
|
|
|
|
|
|
const editStateId = ref(null);
|
|
|
const editUnitIds = ref([]);
|
|
|
+const loadingUser = ref(false);
|
|
|
|
|
|
const isEdit = computed(() => !!route.params.id);
|
|
|
|
|
|
const form = ref({
|
|
|
+ access_scope: "unit",
|
|
|
state: null,
|
|
|
units: [],
|
|
|
user_type: null,
|
|
|
@@ -193,12 +211,14 @@ const { loading, execute } = useSubmitHandler({
|
|
|
|
|
|
onMounted(async () => {
|
|
|
if (!isEdit.value) return;
|
|
|
+ loadingUser.value = true;
|
|
|
try {
|
|
|
const user = await getUserById(route.params.id);
|
|
|
form.value.name = user.name;
|
|
|
form.value.email = user.email;
|
|
|
form.value.cpf = user.cpf;
|
|
|
form.value.user_type = user.user_type;
|
|
|
+ form.value.access_scope = user.access_scope ?? (user.units?.length ? "unit" : "franchisor");
|
|
|
editStateId.value = user.state_id ?? null;
|
|
|
editUnitIds.value = user.units?.map((u) => u.id) ?? [];
|
|
|
if (user.avatar_url) {
|
|
|
@@ -206,6 +226,8 @@ onMounted(async () => {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error("Failed to load user:", error);
|
|
|
+ } finally {
|
|
|
+ loadingUser.value = false;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -213,6 +235,7 @@ function buildFormData() {
|
|
|
const fd = new FormData();
|
|
|
|
|
|
if (avatarFile.value) fd.append("avatar", avatarFile.value);
|
|
|
+ fd.append("access_scope", form.value.access_scope);
|
|
|
if (form.value.state?.value) fd.append("state_id", form.value.state.value);
|
|
|
form.value.units?.forEach((u) => fd.append("unit_ids[]", u.value));
|
|
|
if (form.value.user_type) fd.append("user_type", form.value.user_type);
|
|
|
@@ -230,6 +253,7 @@ function buildUpdateData() {
|
|
|
fd.append("_method", "PUT");
|
|
|
|
|
|
if (avatarFile.value) fd.append("avatar", avatarFile.value);
|
|
|
+ fd.append("access_scope", form.value.access_scope);
|
|
|
if (form.value.state?.value) fd.append("state_id", form.value.state.value);
|
|
|
// Sempre envia unit_ids[] para sincronizar (array vazio limpa todas as unidades)
|
|
|
(form.value.units ?? []).forEach((u) => fd.append("unit_ids[]", u.value));
|
|
|
@@ -259,4 +283,16 @@ function generatePassword() {
|
|
|
form.value.password = password;
|
|
|
form.value.password_confirmation = password;
|
|
|
}
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => form.value.access_scope,
|
|
|
+ (scope, previousScope) => {
|
|
|
+ if (previousScope && !loadingUser.value) form.value.user_type = null;
|
|
|
+ if (scope === "franchisor") {
|
|
|
+ form.value.state = null;
|
|
|
+ form.value.units = [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { flush: "sync" },
|
|
|
+);
|
|
|
</script>
|