media_player_client/src/components/PollingSettingDialog.vue
fangxiang 9d81132329 安卓平台下添加APP下载提示
安卓APP添加版本更新提示
修复所有对话框loading状态下还能被关闭的BUG
2022-09-02 11:14:55 +08:00

476 lines
15 KiB
Vue

<template>
<q-dialog
persistent
v-model="show_dialog"
@before-hide="resetData"
@keydown="
(evt) => {
if (!loading && evt.keyCode == 27) {
show_dialog = false;
}
}
"
>
<q-card class="overflow-hidden" style="overflow-y: scroll; max-width: 50vw">
<q-form @submit="onSubmit">
<q-card-section class="q-ma-none q-pa-sm">
<div class="row">
<div class="col-auto text-h6">
{{ $t("polling setting") }}
</div>
<q-space />
<div>
<q-btn
:loading="loading"
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>
<q-tooltip>
{{ $t("close") }}
</q-tooltip>
</q-btn>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-section style="max-height: 70vh; width: 50vw" class="scroll">
<q-list>
<q-item>
<q-item-section avatar>
<div class="text-h6 q-pb-md">
{{ $t("polling name") }}:
</div></q-item-section
>
<q-item-section
><q-input
v-model="polling_name"
lazy-rules
:placeholder="$t('please input polling name')"
:rules="[
(val) =>
(val && val.length > 0) || $t('Please type something'),
]"
/></q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-table
style="height: 50vh"
:rows="datas"
:columns="columns"
virtual-scroll
:title="$t('polling data') + ':'"
hide-bottom
color="primary"
row-key="name"
:loading="loading"
:rows-per-page-options="[0]"
:virtual-scroll-sticky-size-start="48"
@row-contextmenu="onContextMenu"
ref="polling_table"
>
<template v-slot:loading>
<q-inner-loading showing color="primary" />
</template>
<template v-slot:body-cell="props">
<q-td :props="props">
<div v-if="props.col.name == 'index'">
{{ props.pageIndex + 1 }}
</div>
<div v-else-if="props.col.name == 'uuid'" class="fit">
<q-popup-edit
:ref="'popup_edit' + props.pageIndex"
v-model="props.row.uuid"
>
<q-tree
ref="tree"
:nodes="$store.state.signal_source_tree"
node-key="uuid"
labelKey="name"
default-expand-all
>
<template v-slot:default-header="prop">
<q-item
class="full-width"
:clickable="!prop.node.is_group"
@click="
(evt) => {
props.row.uuid = prop.node.uuid;
$refs[
'popup_edit' + props.pageIndex
]?.hide();
}
"
:style="{
border:
props.value == prop.node.uuid
? '1px solid #aacceec2'
: 'none',
}"
>
<q-item-section avatar>
<q-icon
:name="
prop.node.is_group
? 'img:source_icon/group.png'
: getItemIcon(
prop.node.item_data?.window_type
)
"
color="orange"
size="28px"
class="q-mr-sm"
/>
</q-item-section>
<q-item-section>
<div class="text-weight-bold text-primary">
{{ prop.node.name }}
</div>
</q-item-section>
</q-item>
</template>
</q-tree>
</q-popup-edit>
{{
signals.find(
(element) =>
element && element.uuid == props.row.uuid
)?.name ?? ""
}}
</div>
<div v-else-if="props.col.name == 'delay'">
{{ props.value }}{{ $t("s") }}
<q-popup-edit
v-model="props.row.delay"
:validate="
(val) => !isNaN(parseInt(val)) && parseInt(val) > 9
"
auto-save
v-slot="scope"
>
<q-input
v-model="scope.value"
type="number"
:min="min_delay"
dense
autofocus
:rules="[
(val) =>
(val != null &&
val != undefined &&
val.toString().length > 0) ||
$t('Please type something'),
(val) =>
parseInt(val) >= 10 ||
$t('number must be greater than or equal to ') +
'10',
]"
>
<template v-slot:append>
<span>{{ $t("s") }}</span>
</template>
</q-input>
</q-popup-edit>
</div>
<div v-else>UNKNOW</div>
</q-td>
</template>
</q-table>
</q-item-section>
</q-item>
</q-list>
</q-card-section>
<q-separator />
<q-card-actions align="left">
<q-btn
:loading="loading"
flat
no-caps
:label="$t('add row')"
color="primary"
@click="addRow(false)"
/>
<q-space />
<q-btn
:loading="loading"
flat
:label="$t('Cancel')"
no-caps
color="primary"
v-close-popup
/>
<q-btn
ref="accept"
flat
:label="$t('Accept')"
no-caps
:loading="loading"
type="submit"
color="primary"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
<div>
<q-menu :target="target_dom" v-model="show_context_menu">
<q-list>
<q-item clickable v-close-popup @click="(evt) => deleteRow()">
<q-item-section avatar
><q-icon name="delete" color="red"
/></q-item-section>
<q-item-section>{{ $t("delete row") }}</q-item-section>
</q-item>
<q-item
v-if="false"
clickable
v-close-popup
@click="(evt) => addRow(true)"
>
<q-item-section avatar><q-icon name="add" /></q-item-section>
<q-item-section>{{ $t("add row") }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</div>
</template>
<style scoped>
.disable_tree {
background: #9e9e9e;
cursor: wait;
pointer-events: none;
}
.width_5_1 {
width: 18%;
}
</style>
<script lang="ts">
import { defineComponent, ref, Ref, watch, computed } from "vue";
import { useStore } from "src/store";
import GlobalData from "src/common/GlobalData";
import { useQuasar } from "quasar";
import { useI18n } from "vue-i18n";
import { StringKeyValueEntity } from "src/entities/StringKeyValueEntity";
import { Common } from "src/common/Common";
import { TableAddRowHelper } from "src/common/TableAddRowHelper";
const __MIN_DELAY = 10;
const __DEFAULT_DELAY = 60;
class TableRow {
uuid = "";
delay = __MIN_DELAY;
}
const table_add_row_helper = new TableAddRowHelper();
export default defineComponent({
name: "ComponentPollingSettingDialog",
setup() {
let $store = useStore();
let $q = useQuasar();
let $t = useI18n();
const min_delay = ref(__MIN_DELAY);
let show_dialog = ref(false);
const polling_table: Ref<any> = ref(null);
let loading = ref(false);
let datas: Ref<TableRow[]> = ref([]);
let signals = ref(GlobalData.getInstance().signal_source);
let polling_name = ref("");
const columns = [
{
align: "left",
name: "index",
required: true,
label: $t.t("No."),
sortable: false,
},
{
align: "left",
name: "uuid",
required: true,
label: $t.t("signal source"),
field: "uuid",
sortable: false,
},
{
align: "left",
name: "delay",
label: $t.t("delay"),
field: "delay",
sortable: false,
},
];
let show_context_menu = ref(false);
let target_dom: any = ref(document.body.children[0]);
let current_index = 0;
let _resolve: any = null;
return {
show_dialog,
polling_table,
min_delay,
loading,
datas,
columns,
show_context_menu,
target_dom,
signals,
polling_name,
loga(a: any) {
console.log(a);
},
showDialog(name: string, options: StringKeyValueEntity[] | null) {
show_dialog.value = true;
signals.value = GlobalData.getInstance().signal_source;
if (options) {
datas.value = [];
if (options.length % 2) {
options.splice(options.length - 1, 1);
}
for (let i = 0; i < options.length; i += 2) {
const item_signal = options[i];
const item_delay = options[i + 1];
if (item_signal && item_delay) {
datas.value.push({
uuid: item_signal.value,
delay: parseInt(item_delay.value),
});
}
}
}
polling_name.value = name ?? $t.t("new polling");
},
showDialogAsync(name: string, options: StringKeyValueEntity[] | null) {
return new Promise((resolve) => {
if (_resolve) {
_resolve();
_resolve = null;
}
_resolve = resolve;
show_dialog.value = true;
signals.value = GlobalData.getInstance().signal_source;
if (options) {
datas.value = [];
for (
let i = 0;
i < (options.length % 2 ? options.length - 1 : options.length);
i += 2
) {
const item_signal = options[i];
const item_delay = options[i + 1];
if (item_signal && item_delay) {
datas.value.push({
uuid: item_signal.value,
delay: parseInt(item_delay.value),
});
}
}
}
polling_name.value = name ?? $t.t("new polling");
});
},
resetData() {
loading.value = false;
if (_resolve) {
_resolve();
_resolve = null;
}
},
addRow(insert_flag: boolean = false) {
const item = {
uuid: GlobalData.getInstance().signal_source[0].uuid,
delay: __DEFAULT_DELAY,
};
if (insert_flag) {
datas.value.splice(current_index + 1, 0, item);
(<any>this).$refs["popup_edit" + current_index]?.show();
} else {
datas.value.push(item);
table_add_row_helper.showProup({
refs: (<any>this).$refs,
ref_name: "popup_edit" + (datas.value.length - 1),
delay: 5,
count: 0,
max_count: 5000,
});
}
signals.value = GlobalData.getInstance().signal_source;
},
onContextMenu(
evt: PointerEvent,
row: StringKeyValueEntity,
index: number
) {
evt.preventDefault();
evt.stopPropagation();
target_dom.value = evt.srcElement;
if (row) {
current_index = index;
show_context_menu.value = true;
}
},
deleteRow() {
if (datas.value.length > current_index) {
datas.value.splice(current_index, 1);
}
},
async onSubmit() {
loading.value = true;
try {
let __datas: StringKeyValueEntity[] = [];
for (const item of datas.value) {
if (item) {
__datas.push({
key: "operator_play_signal_source",
value: item.uuid,
});
__datas.push({
key: "param_delay",
value:
item.delay < __MIN_DELAY
? __MIN_DELAY.toString()
: item.delay.toString(),
});
}
}
if (_resolve) {
_resolve({
name: polling_name.value,
datas: __datas,
});
_resolve = null;
}
show_dialog.value = false;
} catch {}
loading.value = false;
},
getItemIcon(item_type: string) {
return Common.getSignalSourceIcon(item_type);
},
};
},
});
</script>