changes
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
padding: 0.4rem 0.6rem;
|
padding: 0.4rem 0.6rem;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
box-shadow: 2px 2px 1px rgba(0, 0, 0, 0.1);
|
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.control:hover .tooltiptext {
|
.control:hover .tooltiptext {
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ function addNew() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function dataevent(v) {
|
function dataevent(v) {
|
||||||
console.log("SearchBox received dataevent:", v); // Debug log
|
// console.log("SearchBox received dataevent:", v); // Debug log
|
||||||
|
|
||||||
if (!v || !v.id) {
|
if (!v || !v.id) {
|
||||||
console.error("Invalid data received in SearchBox:", v);
|
console.error("Invalid data received in SearchBox:", v);
|
||||||
@@ -346,11 +346,11 @@ function dataevent(v) {
|
|||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
// Nếu chưa có trong danh sách, thêm vào đầu
|
// Nếu chưa có trong danh sách, thêm vào đầu
|
||||||
suggestions.value.unshift(v);
|
suggestions.value.unshift(v);
|
||||||
console.log("Added new item to data:", v);
|
// console.log("Added new item to data:", v);
|
||||||
} else {
|
} else {
|
||||||
// Nếu đã có, cập nhật
|
// Nếu đã có, cập nhật
|
||||||
suggestions.value[idx] = v;
|
suggestions.value[idx] = v;
|
||||||
console.log("Updated existing item in data:", v);
|
// console.log("Updated existing item in data:", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cập nhật orgdata nếu có
|
// Cập nhật orgdata nếu có
|
||||||
|
|||||||
@@ -542,7 +542,7 @@ function fieldList() {
|
|||||||
component: "datatable/TableOption",
|
component: "datatable/TableOption",
|
||||||
vbind: { pagename: props.pagename },
|
vbind: { pagename: props.pagename },
|
||||||
title: "Danh sách cột",
|
title: "Danh sách cột",
|
||||||
width: "75%",
|
width: "600px",
|
||||||
height: "630px",
|
height: "630px",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -592,8 +592,8 @@ th a {
|
|||||||
--bulma-table-row-hover-background-color: var(--bulma-scheme-main-ter);
|
--bulma-table-row-hover-background-color: var(--bulma-scheme-main-ter);
|
||||||
background-color: var(--bulma-table-row-hover-background-color);
|
background-color: var(--bulma-table-row-hover-background-color);
|
||||||
}
|
}
|
||||||
.header:hover a {
|
.header:hover {
|
||||||
opacity: 0.75;
|
background-color: hsla(var(--bulma-primary-h), var(--bulma-primary-s), 91%, 1) !important;
|
||||||
}
|
}
|
||||||
.table tbody tr:hover .emptyData {
|
.table tbody tr:hover .emptyData {
|
||||||
background-color: var(--bulma-table-cell-background-color);
|
background-color: var(--bulma-table-cell-background-color);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div :id="id">
|
||||||
<template v-if="keys.length > 0">
|
<template v-if="keys.length > 0">
|
||||||
<div
|
<div
|
||||||
class="field is-horizontal"
|
class="field is-horizontal"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
>
|
>
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<Icon
|
<Icon
|
||||||
name="material-symbols:app-registration-rounded"
|
name="material-symbols:data-object-rounded"
|
||||||
:size="20"
|
:size="20"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@@ -58,37 +58,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<button
|
<Teleport
|
||||||
class="button is-success is-light"
|
defer
|
||||||
@click="addAttr()"
|
:to="`.modal-card:has(#${id}) .modal-card-foot`"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<div class="buttons is-justify-content-space-between w-full">
|
||||||
<Icon
|
<button
|
||||||
name="material-symbols:add-rounded"
|
class="button is-success is-light"
|
||||||
:size="20"
|
@click="addAttr()"
|
||||||
/>
|
>
|
||||||
</span>
|
<span class="icon">
|
||||||
<span>Thêm thuộc tính</span>
|
<Icon
|
||||||
</button>
|
name="material-symbols:add-rounded"
|
||||||
<div class="mt-2">
|
:size="20"
|
||||||
<button
|
/>
|
||||||
class="button is-primary"
|
</span>
|
||||||
@click="update()"
|
<span>Thêm thuộc tính</span>
|
||||||
>
|
</button>
|
||||||
Cập nhật
|
<button
|
||||||
</button>
|
class="button is-primary"
|
||||||
</div>
|
@click="update()"
|
||||||
|
>
|
||||||
|
Cập nhật
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
<Modal
|
<Modal
|
||||||
|
v-if="comp"
|
||||||
|
v-bind="{ component: comp, width: '40%', height: '400px', vbind }"
|
||||||
@close="comp = undefined"
|
@close="comp = undefined"
|
||||||
@update="doUpdate"
|
@update="doUpdate"
|
||||||
v-bind="{ component: comp, width: '40%', height: '300px', vbind: vbind }"
|
/>
|
||||||
v-if="comp"
|
|
||||||
></Modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["field", "close"],
|
props: ["field", "close"],
|
||||||
|
setup() {
|
||||||
|
const id = useId();
|
||||||
|
return { id };
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
keys: [],
|
keys: [],
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
<div class="control is-expanded is-flex is-gap-0.5 fs-14">
|
<div class="control is-expanded is-flex is-gap-0.5 fs-14">
|
||||||
<button
|
<button
|
||||||
:class="['button', radioSave === 'overwrite' ? 'is-primary is-light' : 'is-white']"
|
:class="['button', radioSave === 'overwrite' ? 'is-primary is-light' : 'is-white']"
|
||||||
v-if="isOverwrite()"
|
|
||||||
@click="changeType('overwrite')"
|
@click="changeType('overwrite')"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
? 'material-symbols:radio-button-checked-outline'
|
? 'material-symbols:radio-button-checked-outline'
|
||||||
: 'material-symbols:radio-button-unchecked'
|
: 'material-symbols:radio-button-unchecked'
|
||||||
"
|
"
|
||||||
:size="22"
|
:size="18"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span>Ghi đè</span>
|
<span>Ghi đè</span>
|
||||||
@@ -49,7 +48,7 @@
|
|||||||
? 'material-symbols:radio-button-checked-outline'
|
? 'material-symbols:radio-button-checked-outline'
|
||||||
: 'material-symbols:radio-button-unchecked'
|
: 'material-symbols:radio-button-unchecked'
|
||||||
"
|
"
|
||||||
:size="22"
|
:size="18"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span>Tạo mới</span>
|
<span>Tạo mới</span>
|
||||||
@@ -88,36 +87,29 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="field mt-5 px-0 mx-0">
|
<div class="buttons is-justify-content-flex-end">
|
||||||
<label
|
<button
|
||||||
class="label fs-14"
|
@click="emit('close')"
|
||||||
v-if="status !== undefined"
|
class="button is-white"
|
||||||
:class="status ? 'has-text-primary' : 'has-text-danger'"
|
|
||||||
>
|
>
|
||||||
{{ status ? "Lưu thiết lập thành công." : "Lỗi. Lưu thiết lập thất bại." }}
|
Huỷ
|
||||||
</label>
|
</button>
|
||||||
<p class="control is-expanded">
|
<button
|
||||||
<button
|
ref="saveBtn"
|
||||||
ref="saveBtn"
|
:class="['button is-primary', isLoading && 'is-loading']"
|
||||||
:class="['button is-primary', isLoading && 'is-loading']"
|
@click="saveSetting"
|
||||||
@click="saveSetting"
|
>
|
||||||
>
|
<span class="icon">
|
||||||
<span class="icon">
|
<Icon
|
||||||
<Icon
|
name="material-symbols:check-rounded"
|
||||||
name="material-symbols:check-rounded"
|
:size="18"
|
||||||
:size="18"
|
/>
|
||||||
/>
|
</span>
|
||||||
</span>
|
<span>Lưu lại</span>
|
||||||
<span>Lưu lại</span>
|
</button>
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
|
||||||
|
|
||||||
const emit = defineEmits(["modalevent", "close"]);
|
|
||||||
const store = useStore();
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
pagename: String,
|
pagename: String,
|
||||||
classify: String,
|
classify: String,
|
||||||
@@ -125,8 +117,9 @@ const props = defineProps({
|
|||||||
data: Object,
|
data: Object,
|
||||||
focus: Boolean,
|
focus: Boolean,
|
||||||
});
|
});
|
||||||
|
const emit = defineEmits(["modalevent", "close"]);
|
||||||
|
const store = useStore();
|
||||||
const { $empty, $copy, $patchapi, $insertapi, $findIndex, $snackbar } = useNuxtApp();
|
const { $empty, $copy, $patchapi, $insertapi, $findIndex, $snackbar } = useNuxtApp();
|
||||||
const radioOption = ref();
|
|
||||||
const login = { id: 1 };
|
const login = { id: 1 };
|
||||||
const errors = ref([]);
|
const errors = ref([]);
|
||||||
const radioType = ref();
|
const radioType = ref();
|
||||||
@@ -134,20 +127,28 @@ const radioDefault = 0;
|
|||||||
const radioSave = ref("overwrite");
|
const radioSave = ref("overwrite");
|
||||||
const name = ref();
|
const name = ref();
|
||||||
const note = ref();
|
const note = ref();
|
||||||
const status = undefined;
|
let currentsetting = undefined;
|
||||||
var currentsetting = undefined;
|
const pagedata = store[props.pagename];
|
||||||
var pagename = props.pagename;
|
|
||||||
var pagedata = store[props.pagename];
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const saveBtnRef = useTemplateRef("saveBtn");
|
const saveBtnRef = useTemplateRef("saveBtn");
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
saveBtnRef.value.focus();
|
saveBtnRef.value.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function initData() {
|
||||||
|
radioType.value = store.settingtype.find((v) => v.code === "private");
|
||||||
|
if (props.pagename) currentsetting = $copy(pagedata.setting || undefined);
|
||||||
|
// disable temp: for now, radioSave is always 'overwrite'
|
||||||
|
/* if (!currentsetting) radioSave.value = "new";
|
||||||
|
else if (currentsetting.user !== login.id) radioSave.value = "new";
|
||||||
|
else radioSave.value = "overwrite"; */
|
||||||
|
}
|
||||||
|
initData();
|
||||||
|
|
||||||
async function saveSetting() {
|
async function saveSetting() {
|
||||||
errors.value = [];
|
errors.value = [];
|
||||||
let detail = pagename ? { fields: pagedata.fields } : {};
|
let detail = props.pagename ? { fields: pagedata.fields } : {};
|
||||||
if (pagename) {
|
if (props.pagename) {
|
||||||
let element = pagedata.tablesetting || {};
|
let element = pagedata.tablesetting || {};
|
||||||
if (element !== store.originsetting) detail.tablesetting = element;
|
if (element !== store.originsetting) detail.tablesetting = element;
|
||||||
if (pagedata.filters ? pagedata.filters.length > 0 : false) {
|
if (pagedata.filters ? pagedata.filters.length > 0 : false) {
|
||||||
@@ -202,22 +203,8 @@ async function saveSetting() {
|
|||||||
emit("close");
|
emit("close");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function isOverwrite() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
function changeType(value) {
|
function changeType(value) {
|
||||||
radioSave.value = value;
|
radioSave.value = value;
|
||||||
}
|
}
|
||||||
function changeOption(v) {
|
|
||||||
radioOption.value = v.code;
|
|
||||||
}
|
|
||||||
function initData() {
|
|
||||||
radioType.value = store.settingtype.find((v) => v.code === "private");
|
|
||||||
if (props.pagename) currentsetting = $copy(pagedata.setting ? pagedata.setting : undefined);
|
|
||||||
// disable temp: for now, radioSave is always 'overwrite'
|
|
||||||
/* if (!currentsetting) radioSave.value = "new";
|
|
||||||
else if (currentsetting.user !== login.id) radioSave.value = "new";
|
|
||||||
else radioSave.value = "overwrite"; */
|
|
||||||
}
|
|
||||||
initData();
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="fs-14">
|
<tr class="fs-14">
|
||||||
<th class="is-narrow">#</th>
|
<th class="is-narrow">#</th>
|
||||||
<th>Tên trường</th>
|
<th>Tên</th>
|
||||||
<th>Tên cột</th>
|
|
||||||
<th class="is-narrow has-text-right">Thao tác</th>
|
<th class="is-narrow has-text-right">Thao tác</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -13,16 +12,12 @@
|
|||||||
class="fs-14"
|
class="fs-14"
|
||||||
v-for="(v, i) in fields"
|
v-for="(v, i) in fields"
|
||||||
>
|
>
|
||||||
<td style="vertical-align: middle">{{ i }}</td>
|
<td>{{ i }}</td>
|
||||||
<td style="vertical-align: middle">
|
|
||||||
<a
|
|
||||||
class="has-text-primary"
|
|
||||||
@click="openField(v, i)"
|
|
||||||
>{{ v.name }}</a
|
|
||||||
>
|
|
||||||
</td>
|
|
||||||
<td style="vertical-align: middle">{{ $stripHtml(v.label, 50) }}</td>
|
|
||||||
<td>
|
<td>
|
||||||
|
<p>{{ $stripHtml(v.label, 50) }}</p>
|
||||||
|
<a @click="openField(v, i)">{{ v.name }}</a>
|
||||||
|
</td>
|
||||||
|
<td style="vertical-align: middle">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<button
|
<button
|
||||||
@@ -69,12 +64,12 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<Modal
|
<Modal
|
||||||
|
v-if="showmodal"
|
||||||
|
v-bind="showmodal"
|
||||||
@close="showmodal = undefined"
|
@close="showmodal = undefined"
|
||||||
@update="update"
|
@update="update"
|
||||||
@confirm="remove"
|
@confirm="remove"
|
||||||
v-bind="showmodal"
|
/>
|
||||||
v-if="showmodal"
|
|
||||||
></Modal>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { cloneDeep } from "es-toolkit";
|
import { cloneDeep } from "es-toolkit";
|
||||||
@@ -94,7 +89,7 @@ function openField(v, i) {
|
|||||||
component: "datatable/FieldAttribute",
|
component: "datatable/FieldAttribute",
|
||||||
title: `${v.name} / ${$stripHtml(v.label)}`,
|
title: `${v.name} / ${$stripHtml(v.label)}`,
|
||||||
width: "50%",
|
width: "50%",
|
||||||
height: "400px",
|
height: "500px",
|
||||||
vbind: { field: v },
|
vbind: { field: v },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -124,13 +119,13 @@ function moveUp(v, i) {
|
|||||||
updateField();
|
updateField();
|
||||||
}
|
}
|
||||||
function askConfirm(v, i) {
|
function askConfirm(v, i) {
|
||||||
current = { v: v, i: i };
|
current = { v, i };
|
||||||
showmodal.value = {
|
showmodal.value = {
|
||||||
component: `dialog/Confirm`,
|
component: "dialog/Confirm",
|
||||||
vbind: { content: "Bạn có muốn xóa cột này không?", duration: 10 },
|
vbind: { content: `Bạn có muốn xóa cột <span class="tag">${v.name}</span> không?` },
|
||||||
title: "Xóa cột",
|
title: "Xóa cột",
|
||||||
width: "500px",
|
width: "500px",
|
||||||
height: "100px",
|
height: "auto",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function remove() {
|
function remove() {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ const props = defineProps({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a
|
<a
|
||||||
|
class="tag fs-12 is-rounded is-primary is-light"
|
||||||
|
style="border: 1px solid var(--bulma-primary-90)"
|
||||||
@click="
|
@click="
|
||||||
$emit('clickevent', {
|
$emit('clickevent', {
|
||||||
name: 'dataevent',
|
name: 'dataevent',
|
||||||
@@ -14,17 +16,12 @@ const props = defineProps({
|
|||||||
component: 'imports/IMEIs',
|
component: 'imports/IMEIs',
|
||||||
title: 'IMEIs',
|
title: 'IMEIs',
|
||||||
width: '80%',
|
width: '80%',
|
||||||
vbind: { variant: props.variant },
|
vbind: { variant },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
{{ variant.imei_count }}
|
||||||
<Icon
|
|
||||||
name="mdi:launch"
|
|
||||||
:size="18"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import DataView from "~/components/datatable/DataView.vue";
|
|||||||
params: {
|
params: {
|
||||||
values:
|
values:
|
||||||
'id,code,product,product__name,product__os__name,product__external_storage__max_capacity,color,color__code,color__name,color__hex_code,ram,ram__code,ram__capacity,internal_storage,internal_storage__code,internal_storage__capacity,image,image__path,price,note,create_time,update_time',
|
'id,code,product,product__name,product__os__name,product__external_storage__max_capacity,color,color__code,color__name,color__hex_code,ram,ram__code,ram__capacity,internal_storage,internal_storage__code,internal_storage__capacity,image,image__path,price,note,create_time,update_time',
|
||||||
|
distinct_values: {
|
||||||
|
imei_count: { type: 'Count', field: 'imeis' },
|
||||||
|
},
|
||||||
|
summary: 'annotate',
|
||||||
sort: 'id',
|
sort: 'id',
|
||||||
},
|
},
|
||||||
timeopt: { time: 36000 },
|
timeopt: { time: 36000 },
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
ref="file-input"
|
ref="file-input"
|
||||||
type="file"
|
type="file"
|
||||||
:id="$id()"
|
:id="$id()"
|
||||||
:multiple="multiple ?? true"
|
:multiple="multiple"
|
||||||
name="resume"
|
name="resume"
|
||||||
@change="doChange"
|
@change="doChange"
|
||||||
/>
|
/>
|
||||||
@@ -48,7 +48,10 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
convert: String,
|
convert: String,
|
||||||
quality: Number,
|
quality: Number,
|
||||||
multiple: Boolean,
|
multiple: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["files"]);
|
const emit = defineEmits(["files"]);
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
let rs;
|
let rs;
|
||||||
|
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
rs = await $fetch(`${curpath}import-data/${api.url.substring(5, api.url.length - 1)}/`, {
|
const model = api.url.slice(5);
|
||||||
|
rs = await $fetch(`${curpath}import-data/${model}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
params: { values, action: "import" },
|
params: { values, action: "import" },
|
||||||
|
|||||||
Reference in New Issue
Block a user