ntopng/http_src/vue/modal-import-assets.vue
2025-09-22 21:37:38 +02:00

130 lines
No EOL
3.5 KiB
Vue

<!-- (C) 2022 - ntop.org -->
<template>
<modal @showed="showed()" ref="modal_id">
<template v-slot:title>{{ title }}</template>
<template v-slot:body>
<!-- Target information, here an IP is put -->
<div class="custom-file">
<label class='form-label' for='import-input'>
{{ _i18n("asset_details.browse_assets", {}) }}
</label>
<input required class="custom-file-input form-control" ref="import_input" id="import-input" name="CSV"
type="file" @change="handleFileUpload" accept=".csv" />
</div>
</template>
<template v-slot:footer>
<div class="w-100">
<NoteList :note_list="note_list"> </NoteList>
</div>
<div v-if="is_data_not_ok" class="me-auto text-danger d-inline">
{{ message }}
</div>
<div>
<Spinner :show="activate_import_spinner" size="1rem" class="me-2"></Spinner>
<button type="button" :disabled="!is_not_empty_file" @click="_import" class="btn btn-primary">{{
_i18n('import')
}}</button>
</div>
</template>
</modal>
</template>
<script setup>
import { ref } from "vue";
import { default as modal } from "./modal.vue";
import { default as Spinner } from "./spinner.vue";
import { default as NoteList } from "./note-list.vue";
const modal_id = ref(null);
const emit = defineEmits(['add', 'edit']);
const _i18n = (t) => i18n(t);
const activate_import_spinner = ref(false);
const is_data_not_ok = ref(false);
const is_not_empty_file = ref(false);
let title = _i18n('asset_details.import');
let message = "";
const max_size_mb = 2000000; // keep in sync with en.lua -> assets_file_too_large
const json_file = ref(null);
const import_input = ref(null);
const note_list = [
i18n("asset_details.import_assets_notes")
];
const showed = () => { };
const props = defineProps({
ifid_list: Array,
frequency_list: Array,
init_func: Function,
page_csrf: String,
});
/**
*
* Reset fields in modal form
*/
const reset_modal_form = function () {
json_file.value = null;
activate_import_spinner.value = false;
is_data_not_ok.value = false;
is_not_empty_file.value = false;
import_input.value.value = null;
}
const show = (row) => {
reset_modal_form();
modal_id.value.show();
};
const handleFileUpload = (event) => {
json_file.value = event.target.files[0];
const size_MB = json_file.value.size / 1000;
is_not_empty_file.value = json_file.value != null && size_MB < max_size_mb; //2MB
if (size_MB > max_size_mb) {
is_data_not_ok.value = true;
message = _i18n("assets_file_too_large")
} else {
is_data_not_ok.value = false;
message = "";
}
}
const _import = (is_edit) => {
activate_import_spinner.value = true;
is_data_not_ok.value = false;
const fileReader = new FileReader();
fileReader.readAsText(json_file.value, "UTF-8");
fileReader.onload = () => {
emit('add', {
assets: fileReader.result
});
};
};
const show_bad_feedback = (bad_message) => {
message = bad_message;
is_data_not_ok.value = true;
activate_import_spinner.value = false;
};
const close = () => {
activate_import_spinner.value = false;
is_data_not_ok.value = false;
modal_id.value.close();
};
defineExpose({ show, close, show_bad_feedback });
</script>
<style scoped></style>