before delete 3software
This commit is contained in:
@@ -1,102 +1,150 @@
|
||||
<template>
|
||||
<pn-page-card>
|
||||
<template #title>
|
||||
<div class="col-grow">
|
||||
{{$t('company__mask')}}
|
||||
</div>
|
||||
{{$t('company__mask')}}
|
||||
<q-btn
|
||||
v-if="!checkIsDirty(mask, originalMask)"
|
||||
@click = "updateCompanies()"
|
||||
flat round
|
||||
icon="mdi-check"
|
||||
/>
|
||||
</template>
|
||||
<pn-scroll-list>
|
||||
<template #card-body-header>
|
||||
<div style="min-height: var(--top-raduis);"/>
|
||||
</template>
|
||||
<q-list
|
||||
separator
|
||||
<q-table
|
||||
flat
|
||||
:rows="displayCompanies"
|
||||
:columns="tableColumns"
|
||||
hide-pagination
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
dense
|
||||
row-key="id"
|
||||
style="max-width: 100% !important"
|
||||
>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<div>
|
||||
<q-btn flat round color="primary" icon="mdi-help-circle-outline" @click="showDialogHelp = true" />
|
||||
</div>
|
||||
</q-item-section>
|
||||
<q-item-section></q-item-section>
|
||||
<q-item-section align="end" class="col-grow">
|
||||
{{ $t('mask__title_table') }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-for = "company in companies"
|
||||
:key="company.id"
|
||||
class="w100"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
v-model="company.masked"
|
||||
:label="company.name"
|
||||
unchecked-icon="mdi-drama-masks"
|
||||
checked-icon="mdi-drama-masks"
|
||||
:class="company.masked ? 'masked' : 'unmasked'"
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-select
|
||||
v-if="company.masked"
|
||||
v-model="company.unmasked"
|
||||
multiple
|
||||
:options="companiesSelect(company.id)"
|
||||
dense
|
||||
borderless
|
||||
dropdown-icon="mdi-plus"
|
||||
class="fix-select"
|
||||
>
|
||||
<template #selected>
|
||||
<div
|
||||
v-for="(comp, idx) in company.unmasked"
|
||||
:key=idx
|
||||
class="q-pa-xs"
|
||||
>
|
||||
<q-avatar rounded size="md">
|
||||
<img v-if="comp['logo']" :src="comp['logo']"/>
|
||||
<pn-auto-avatar v-else :name="comp['name']"/>
|
||||
</q-avatar>
|
||||
</div>
|
||||
<template #header>
|
||||
<q-tr>
|
||||
<q-th style="width: 10%">
|
||||
<q-icon name="mdi-domino-mask" size="sm"/>
|
||||
</q-th>
|
||||
<q-th style="width: 45%">
|
||||
<span class="text-bold">
|
||||
{{ $t('mask__table_header_company') }}
|
||||
</span>
|
||||
</q-th>
|
||||
<q-th style="width: 45%">
|
||||
<span class="text-bold">
|
||||
{{ $t('mask__table_header_visible') }}
|
||||
<q-btn
|
||||
flat
|
||||
@click="showDialogHelp=true"
|
||||
color="primary"
|
||||
dense round
|
||||
size="sm"
|
||||
icon="mdi-help-circle-outline"
|
||||
/>
|
||||
</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
|
||||
<template #body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td key="checkbox" :props="props">
|
||||
<q-toggle
|
||||
v-model="props.row.masked"
|
||||
size="sm"
|
||||
:color="props.row.masked ? 'red' : 'brand'"
|
||||
/>
|
||||
</q-td>
|
||||
<q-td key="name" :props="props">
|
||||
{{ props.row.name }}
|
||||
</q-td>
|
||||
<q-td key="visible" :props="props">
|
||||
<q-select
|
||||
v-if="props.row.masked"
|
||||
v-model="props.row.company_list"
|
||||
multiple
|
||||
:options="companiesSelect(props.row.id)"
|
||||
option-value="id"
|
||||
emit-value
|
||||
dense
|
||||
borderless
|
||||
dropdown-icon="mdi-plus"
|
||||
class="fix-select"
|
||||
:label-slot="!props.row.hasFocus && !props.row.isMenuOpen && (props.row.company_list.length === 0)"
|
||||
@popup-show="props.row.isMenuOpen = true"
|
||||
@popup-hide="props.row.isMenuOpen = false"
|
||||
@focus="props.row.hasFocus = true"
|
||||
@blur="props.row.hasFocus = false"
|
||||
>
|
||||
<template #label>
|
||||
<span
|
||||
v-if="(!props.row.hasFocus || !props.row.isMenuOpen) && (props.row.company_list.length === 0)"
|
||||
class="q-field__label"
|
||||
>
|
||||
{{ $t('mask__table_visible_none') }}
|
||||
</span>
|
||||
</template>
|
||||
<template #option="scope">
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section avatar>
|
||||
<q-avatar rounded size="md">
|
||||
<img v-if="scope.opt.logo" :src="scope.opt.logo"/>
|
||||
<pn-auto-avatar v-else :name="scope.opt.name"/>
|
||||
</q-avatar>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ scope.opt.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
class="q-pa-none q-ma-none"
|
||||
style="min-height: 18px"
|
||||
>
|
||||
<div class="q-py-none flex column w100"/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<template #selected>
|
||||
<div
|
||||
v-for="id in props.row.company_list"
|
||||
:key=id
|
||||
class="q-pa-xs"
|
||||
>
|
||||
<pn-auto-avatar
|
||||
:img="getCompanyById(id)?.logo"
|
||||
:name="getCompanyById(id)?.name"
|
||||
size="md"
|
||||
type="rounded"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #option="scope">
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section avatar>
|
||||
<pn-auto-avatar
|
||||
:img="scope.opt.logo"
|
||||
:name="scope.opt.name"
|
||||
size="md"
|
||||
type="rounded"
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ scope.opt.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
<span
|
||||
v-else
|
||||
>
|
||||
{{ $t('mask__table_visible_all') }}
|
||||
</span>
|
||||
</q-td>
|
||||
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
<div class="q-py-none flex column w100" style="min-height: 18px"/>
|
||||
</pn-scroll-list>
|
||||
|
||||
<q-dialog v-model="showDialogHelp">
|
||||
<q-card class="q-ma-sm w100">
|
||||
<q-card-section class="row items-center q-pb-none">
|
||||
<span class="text-h6">
|
||||
<q-icon name="mdi-drama-masks"/>
|
||||
<q-icon name="mdi-domino-mask"/>
|
||||
{{ $t('mask__help_title')}}
|
||||
</span>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pt-sm">
|
||||
{{ $t('mask__help_message')}}
|
||||
<p>{{ $t('mask__help_message1')}}</p>
|
||||
<p>{{ $t('mask__help_message2')}}</p>
|
||||
<p>{{ $t('mask__help_message3')}}</p>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
@@ -104,26 +152,53 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
// import { useCompaniesStore } from 'src/stores/companies'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useCompaniesStore } from 'stores/companies'
|
||||
import type { CompanyMask } from 'types/Company'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const showDialogHelp = ref<boolean>(false)
|
||||
// const companiesStore = useCompaniesStore()
|
||||
const companiesStore = useCompaniesStore()
|
||||
const router = useRouter()
|
||||
|
||||
// const companies = computed(() => companiesStore.companies)
|
||||
const companies = computed(() => companiesStore.companies)
|
||||
const companiesMask = computed(() => companiesStore.companiesMask)
|
||||
|
||||
const companies = ref([
|
||||
{id: "com11", name: 'Рога и копытца1', logo: '', description: 'Монтажники вывески', qtyPersons: 3, masked: false, unmasked: [] },
|
||||
{id: "com21", name: 'ООО "Василек1"', logo: 'https://cdn.quasar.dev/img/avatar5.jpg', qtyPersons: 2, masked: true, unmasked: [] },
|
||||
{id: "ch13", name: 'Откат и деньги1', logo: 'https://cdn.quasar.dev/img/avatar4.jpg', description: 'Договариваются с администрацией', qtyPersons: 5, masked: false, unmasked: [] },
|
||||
{id: "ch14", name: 'Откат и деньги2', logo: '', description: 'Договариваются о чем-то', qtyPersons: 5, masked: false, unmasked: [] },
|
||||
{id: "com111", name: 'Рога и копытца2', logo: '', description: 'Монтажники вывески', qtyPersons: 3, masked: false, unmasked: []},
|
||||
{id: "com211", name: 'ООО "Василек2"', logo: '', qtyPersons: 2, masked: true, unmasked: [] },
|
||||
{id: "ch131", name: 'Откат и деньги3', logo: '', description: 'Договариваются с администрацией', qtyPersons: 5, masked: false, unmasked: [] },
|
||||
])
|
||||
interface DisplayCompany {
|
||||
id: number
|
||||
name: string
|
||||
logo?: string
|
||||
masked: boolean
|
||||
company_list: number[],
|
||||
isMenuOpen: boolean
|
||||
hasFocus: boolean
|
||||
}
|
||||
|
||||
function companiesSelect (id :string) {
|
||||
return companies.value
|
||||
//
|
||||
const displayCompanies = ref<DisplayCompany[]>([])
|
||||
const originalMask = ref<CompanyMask[]>([])
|
||||
|
||||
const tableColumns = [
|
||||
{ name: 'checkbox', field: 'checkbox', label: 'checkbox', sortable: false, style: "width: 10%" },
|
||||
{ name: 'name', field: 'name', align: 'left' as const, label: 'name', sortable: false, style: "width: 45% !important; text-wrap: auto" },
|
||||
{ name: 'visible', field: 'visible', align: 'center' as const, label: 'visible', sortable: false, style: "width: 45% !important" }
|
||||
]
|
||||
|
||||
const mask = computed(() => displayCompanies.value
|
||||
.filter(el => el.masked)
|
||||
.map(el => ({
|
||||
company_id: el.id,
|
||||
company_list: el.company_list.sort(compareNumbers)
|
||||
}))
|
||||
.sort((a, b) => compareNumbers(a.company_id, b.company_id))
|
||||
)
|
||||
|
||||
function getCompanyById(id: number) {
|
||||
return companies.value.find(c => c.id === id);
|
||||
}
|
||||
|
||||
function companiesSelect (id :number) {
|
||||
return displayCompanies.value
|
||||
.map(el => ({
|
||||
id: el.id,
|
||||
name: el.name,
|
||||
@@ -132,26 +207,103 @@
|
||||
.filter(el => el.id !== id)
|
||||
}
|
||||
|
||||
async function updateCompanies () {
|
||||
await companiesStore.updateMask(mask.value)
|
||||
router.back()
|
||||
}
|
||||
|
||||
function compareNumbers (a: number, b: number): number {
|
||||
if (Number.isNaN(a)) return Number.isNaN(b) ? 0 : 1
|
||||
if (Number.isNaN(b)) return -1
|
||||
|
||||
if (a === b) return 0
|
||||
return a < b ? -1 : 1
|
||||
}
|
||||
|
||||
function checkIsDirty (arr1: CompanyMask[], arr2: CompanyMask[]): boolean {
|
||||
// Проверка длины массивов
|
||||
if (arr1.length !== arr2.length) return false
|
||||
|
||||
// Функция для нормализации объекта в строковый ключ
|
||||
const getKey = (obj: { company_id: number; company_list: number[] }): string => {
|
||||
const sortedList = [...obj.company_list].sort(compareNumbers)
|
||||
return `${obj.company_id}|${sortedList.join(',')}`
|
||||
}
|
||||
|
||||
// Создаем Map для подсчета объектов в первом массиве
|
||||
const countMap = new Map<string, number>()
|
||||
for (const item of arr1) {
|
||||
const key = getKey(item)
|
||||
countMap.set(key, (countMap.get(key) || 0) + 1)
|
||||
}
|
||||
|
||||
// Проверяем объекты второго массива
|
||||
for (const item of arr2) {
|
||||
const key = getKey(item)
|
||||
const count = countMap.get(key) || 0
|
||||
|
||||
if (count === 0) return false
|
||||
|
||||
countMap.set(key, count - 1)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
function getList (companyId: number) {
|
||||
const company = companiesMask.value.find(el => el.company_id === companyId)
|
||||
return company?.company_list ?? []
|
||||
}
|
||||
|
||||
displayCompanies.value = companies.value
|
||||
.filter(el => !el.is_own)
|
||||
.map(el => ({
|
||||
id: el.id,
|
||||
name: el.name,
|
||||
logo: el?.logo ?? '',
|
||||
masked: companiesStore.checkCompanyMasked(el.id),
|
||||
company_list: getList(el.id),
|
||||
isMenuOpen: false,
|
||||
hasFocus: false
|
||||
}))
|
||||
|
||||
console.log(companies.value)
|
||||
console.log(displayCompanies.value)
|
||||
|
||||
originalMask.value = [ ...(companiesMask.value.sort((a, b) => compareNumbers(a.company_id, b.company_id))) ]
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
:deep(.fix-select .q-field__control) {
|
||||
.fix-select :deep(.q-field__control) {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fix-select :deep(.q-field__native) {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.fix-select :deep(.q-field__label.no-pointer-events) {
|
||||
left: 50% !important;
|
||||
transform: translateX(-50%) !important;
|
||||
}
|
||||
|
||||
:deep(.fix-select .q-icon) {
|
||||
color: $green-14 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
:deep(.masked .q-icon) {
|
||||
color: red;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
:deep(.unmasked .q-icon) {
|
||||
color: grey;
|
||||
opacity: 0.5;
|
||||
color: 'brand';
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user