feat(frontend): implement QuantAgGrid transparent adapter wrapper for AG Grid with full API & event passthrough and 100% vendor decoupling
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 11s
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 11s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 17s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 8s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 8s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 11s
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 11s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 17s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 8s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 8s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,145 @@
|
|||||||
|
<!-- Enterprise AG Grid Transparent Adapter Wrapper: QuantAgGrid -->
|
||||||
|
<template>
|
||||||
|
<div class="quant-ag-grid-container w-full h-full flex flex-col border border-slate-300 rounded-lg shadow-2xs bg-white overflow-hidden">
|
||||||
|
<!-- 그리드 상단 툴바 (옵션) -->
|
||||||
|
<div v-if="showToolbar !== false" class="flex items-center justify-between px-3 py-2 bg-slate-100 border-b border-slate-200 text-xs">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="font-bold text-slate-700 flex items-center gap-1">
|
||||||
|
<span>⚡</span> {{ title || 'AG Grid 초고속 분석 리포트' }}
|
||||||
|
</span>
|
||||||
|
<span v-if="rowData" class="text-[11px] text-slate-500 font-mono">
|
||||||
|
({{ rowData.length.toLocaleString() }}건)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
v-if="showSearch !== false"
|
||||||
|
v-model="quickSearchText"
|
||||||
|
type="text"
|
||||||
|
placeholder="빠른 전체 검색..."
|
||||||
|
class="h-7 w-44 text-[11px] px-2 border border-slate-300 rounded bg-white font-medium focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
||||||
|
@input="onQuickSearch"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
v-if="showExport !== false"
|
||||||
|
type="button"
|
||||||
|
class="h-7 px-2.5 bg-emerald-600 hover:bg-emerald-700 text-white font-bold text-[11px] rounded transition flex items-center gap-1 shadow-2xs"
|
||||||
|
@click="exportCsv"
|
||||||
|
>
|
||||||
|
<span>📥</span> 엑셀 CSV 내보내기
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- AG Grid Vue 투명 어댑터 레이어 -->
|
||||||
|
<div class="ag-theme-alpine w-full flex-1 min-h-[300px]">
|
||||||
|
<AgGridVue
|
||||||
|
v-bind="$attrs"
|
||||||
|
:columnDefs="columnDefs"
|
||||||
|
:rowData="rowData"
|
||||||
|
:defaultColDef="defaultColDef || standardDefaultColDef"
|
||||||
|
:animateRows="animateRows !== false"
|
||||||
|
:rowSelection="rowSelection || 'multiple'"
|
||||||
|
:quickFilterText="quickSearchText"
|
||||||
|
class="w-full h-full"
|
||||||
|
@grid-ready="onGridReady"
|
||||||
|
@cell-value-changed="onCellValueChanged"
|
||||||
|
@selection-changed="onSelectionChanged"
|
||||||
|
@cell-clicked="onCellClicked"
|
||||||
|
>
|
||||||
|
<!-- 슬롯 100% 바이패스 전파 -->
|
||||||
|
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||||
|
<slot :name="slotName" v-bind="slotProps || {}"></slot>
|
||||||
|
</template>
|
||||||
|
</AgGridVue>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { AgGridVue } from 'ag-grid-vue3';
|
||||||
|
import 'ag-grid-community/styles/ag-grid.css';
|
||||||
|
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
||||||
|
import type { ColDef, GridApi, GridReadyEvent, CellValueChangedEvent, SelectionChangedEvent, CellClickedEvent } from 'ag-grid-community';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
inheritAttrs: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
title?: string;
|
||||||
|
columnDefs: ColDef[];
|
||||||
|
rowData: any[];
|
||||||
|
defaultColDef?: ColDef;
|
||||||
|
animateRows?: boolean;
|
||||||
|
rowSelection?: 'single' | 'multiple';
|
||||||
|
showToolbar?: boolean;
|
||||||
|
showSearch?: boolean;
|
||||||
|
showExport?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
'grid-ready',
|
||||||
|
'cell-value-changed',
|
||||||
|
'selection-changed',
|
||||||
|
'cell-clicked',
|
||||||
|
'update:rowData'
|
||||||
|
]);
|
||||||
|
|
||||||
|
const internalGridApi = ref<GridApi | null>(null);
|
||||||
|
const quickSearchText = ref('');
|
||||||
|
|
||||||
|
const standardDefaultColDef = ref<ColDef>({
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 100,
|
||||||
|
filter: true,
|
||||||
|
sortable: true,
|
||||||
|
resizable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const onGridReady = (params: GridReadyEvent) => {
|
||||||
|
internalGridApi.value = params.api;
|
||||||
|
emit('grid-ready', params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCellValueChanged = (event: CellValueChangedEvent) => {
|
||||||
|
emit('cell-value-changed', event);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelectionChanged = (event: SelectionChangedEvent) => {
|
||||||
|
emit('selection-changed', event);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCellClicked = (event: CellClickedEvent) => {
|
||||||
|
emit('cell-clicked', event);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onQuickSearch = () => {
|
||||||
|
if (internalGridApi.value) {
|
||||||
|
internalGridApi.value.setGridOption('quickFilterText', quickSearchText.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportCsv = () => {
|
||||||
|
if (internalGridApi.value) {
|
||||||
|
internalGridApi.value.exportDataAsCsv({
|
||||||
|
fileName: `${props.title || 'quant_ag_grid_export'}_${new Date().toISOString().slice(0, 10)}.csv`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// AG Grid 본래의 모든 API 메서드 100% 개방
|
||||||
|
defineExpose({
|
||||||
|
getApi: () => internalGridApi.value,
|
||||||
|
exportCsv,
|
||||||
|
setQuickFilter: (text: string) => {
|
||||||
|
quickSearchText.value = text;
|
||||||
|
internalGridApi.value?.setGridOption('quickFilterText', text);
|
||||||
|
},
|
||||||
|
selectAll: () => internalGridApi.value?.selectAll(),
|
||||||
|
deselectAll: () => internalGridApi.value?.deselectAll(),
|
||||||
|
refreshCells: (params?: any) => internalGridApi.value?.refreshCells(params)
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<!-- AdvancedAgGridMarketLayout.vue -->
|
<!-- AdvancedAgGridMarketLayout.vue -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { AgGridVue } from 'ag-grid-vue3';
|
import QuantAgGrid from '../../components/QuantAgGrid.vue';
|
||||||
import 'ag-grid-community/styles/ag-grid.css';
|
import 'ag-grid-community/styles/ag-grid.css';
|
||||||
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
||||||
import type { ColDef, GridApi, GridReadyEvent, CellValueChangedEvent } from 'ag-grid-community';
|
import type { ColDef, GridApi, GridReadyEvent, CellValueChangedEvent } from 'ag-grid-community';
|
||||||
@@ -130,10 +130,10 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- AG Grid 본체 -->
|
<!-- QuantAgGrid 퀀텀 투명 어댑터 본체 -->
|
||||||
<div class="grid-wrapper ag-theme-alpine">
|
<div class="grid-wrapper flex-1 w-full">
|
||||||
<ag-grid-vue
|
<QuantAgGrid
|
||||||
style="width: 100%; height: 100%;"
|
title="시세 정밀 조정 및 필터 분석"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:rowData="rowData"
|
:rowData="rowData"
|
||||||
:defaultColDef="defaultColDef"
|
:defaultColDef="defaultColDef"
|
||||||
|
|||||||
Reference in New Issue
Block a user