Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Repository Guidelines

## Icons

- Prefer Lucide icons when adding or replacing icons. Do not use Element Plus icons when a suitable Lucide icon exists.
- Lucide icons are auto-imported; do not add manual imports for them.
- In Vue templates, use kebab-case components with the `i-lucide-` prefix, for example `<i-lucide-eye />`.
- In TSX templates, use the auto-imported `ILucide` PascalCase component name, for example `<ILucideEye />`.
- When an icon is referenced as a component variable or passed as a variable value in TS/TSX or script code, use the auto-imported `IconLucide` PascalCase name, for example `const icon = IconLucideEye` or `icon={IconLucideEye}`.
- Except inside an `el-button`/`ElButton` icon slot, wrap rendered Lucide icons with `el-icon`/`ElIcon`.
- Set icon `size`, `color`, spacing, and other presentation classes on the `el-icon`/`ElIcon` wrapper rather than on the Lucide component. For example, use `<el-icon :size="14" class="view-icon"><i-lucide-eye /></el-icon>` in Vue templates and `<ElIcon size={14} class="view-icon"><ILucideEye /></ElIcon>` in TSX.
- Inside an `el-button`/`ElButton` icon slot, the Lucide component may be used directly because the button provides the icon wrapper and sizing context.

## TypeScript and Validation

- Parts of the existing codebase intentionally lack complete TypeScript typing. Do not expand the task to retrofit types in unrelated existing code.
- Add reasonable, focused types for newly introduced TypeScript/TSX code and for existing declarations that must change to support the new code.
- Do not run repository-wide type checks or builds by default for localized changes. These checks may fail because of unrelated legacy issues and are not required unless the user explicitly requests them.
- Prefer targeted inspection or lightweight checks when validation is useful, without treating unrelated existing type errors as part of the task.
6 changes: 5 additions & 1 deletion packages/assets/styles/utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@
vertical-align: text-top !important;
}

.align-icon-text {
vertical-align: -0.125em !important;
}

.float-start {
float: left !important;
}
Expand Down Expand Up @@ -13241,4 +13245,4 @@

.text-amber-500 {
color: oklch(76.9% 0.188 70.08);
}
}
2 changes: 1 addition & 1 deletion packages/dag/src/components/LeftSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export default {
'source.id': this.activeConnection.id,
taskId: this.$store.state.dataflow.taskId,
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand Down
2 changes: 1 addition & 1 deletion packages/dag/src/components/NodesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const handleFetchTables = async () => {
size: tableState.pageSize,
where: {
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand Down
10 changes: 8 additions & 2 deletions packages/dag/src/components/elements/NodesPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,10 @@ defineExpose({
<div
class="flex align-center justify-center p-1.5 bg-gray-100 dark:bg-white/15 rounded-lg"
>
<el-icon :size="16"><i-lucide-table /></el-icon>
<el-icon :size="16">
<i-lucide-eye v-if="item.meta_type === 'view'" />
<i-lucide-table v-else />
</el-icon>
</div>

<div>
Expand Down Expand Up @@ -732,7 +735,10 @@ defineExpose({
class="flex h-8 align-center gap-2 px-3 connection-item rounded-lg user-select-none"
@click="onClickTable(item)"
>
<el-icon :size="16"><i-lucide-table /></el-icon>
<el-icon :size="16">
<i-lucide-eye v-if="item.meta_type === 'view'" />
<i-lucide-table v-else />
</el-icon>
<OverflowTooltip
class="text-truncate"
:text="item.name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const loadSchemaTree = observer(
where: {
'source.id': connectionId,
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand Down
39 changes: 28 additions & 11 deletions packages/dag/src/components/form/table-list-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ import { getPrimaryKeyTablesByType } from '../../../util'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import './style.scss'

interface TableMetadata {
tableName: string
tableComment?: string
primaryKeyCounts?: number
uniqueIndexCounts?: number
meta_type?: string
}

interface TableListItem {
tableName: string
}

export const TableListCard = observer(
defineComponent({
props: [
Expand All @@ -26,9 +38,10 @@ export const TableListCard = observer(
],
setup(props) {
const loading = ref(false)
const list = ref([])
const list = ref<TableListItem[]>([])
const total = ref(0)
const tableMap = ref({})
const tableNames = ref<string[]>([])
const tableMap = ref<Record<string, TableMetadata>>({})

const loadData = () => {
loading.value = true
Expand All @@ -42,16 +55,15 @@ export const TableListCard = observer(
: getPageTables(params)

fn.then((data) => {
const map = {}
const items = data?.items || []
const map: Record<string, TableMetadata> = {}
const items: TableMetadata[] = data?.items || []
items.forEach((t) => {
if (t.uniqueIndexCounts || t.primaryKeyCounts) {
map[t.tableName] = t
}
map[t.tableName] = t
})
tableMap.value = map
tableNames.value = items.map((t) => t.tableName)
list.value = getPrimaryKeyTablesByType(
items.map((t) => t.tableName) || [],
tableNames.value,
props.filterType,
tableMap.value,
).map((tableName) => ({ tableName }))
Expand All @@ -65,7 +77,7 @@ export const TableListCard = observer(
() => props.filterType,
() => {
list.value = getPrimaryKeyTablesByType(
list.value.map((t) => t.tableName) || [],
tableNames.value,
props.filterType,
tableMap.value,
).map((tableName) => ({ tableName }))
Expand Down Expand Up @@ -93,8 +105,13 @@ export const TableListCard = observer(
placement="right"
open-delay={400}
>
<span>
<span class="align-middle">{name}</span>
<span class="flex align-center">
{tableMap.value[name]?.meta_type === 'view' && (
<el-icon size={14} class="mr-1 color-primary">
<ILucideEye />
</el-icon>
)}
<span>{name}</span>
{tableMap.value[name]?.tableComment && (
<span class="font-color-sslight align-middle">{`(${tableMap.value[name].tableComment})`}</span>
)}
Expand Down
9 changes: 9 additions & 0 deletions packages/dag/src/components/form/table-list-card/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

.table-list-view-icon {
color: color-mix(
in srgb,
var(--el-text-color-secondary) 72%,
var(--color-primary)
);
}

&:hover {
background-color: var(--fill-hover);
}
Expand Down
14 changes: 14 additions & 0 deletions packages/dag/src/components/form/table-select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,20 @@ export const TableSelect = connect(
{i18n.t('public_data_no_data')}
</p>
),
option: ({ item }) => {
return (
<span class="inline-flex align-center gap-2">
<el-icon size={16}>
{item.meta_type === 'view' ? (
<i-lucide-eye />
) : (
<i-lucide-table />
)}
</el-icon>
<span>{item.value}</span>
</span>
)
},
}

if (props.allowCreate) {
Expand Down
41 changes: 37 additions & 4 deletions packages/dag/src/components/form/table-selector/TableSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const dataflowStore = useDataflowStore()
const { t } = useI18n()

interface TableMetadata {
tableComment?: string
primaryKeyCounts?: number
uniqueIndexCounts?: number
meta_type?: string
}

// Props
const props = defineProps({
connectionId: {
Expand Down Expand Up @@ -51,7 +58,7 @@ const isOpenClipMode = ref(false)
const isFocus = ref(false)
const clipboardValue = ref('')
const errorTables = ref({})
const tableMap = ref({})
const tableMap = ref<Record<string, TableMetadata>>({})
const table = ref({
tables: [] as string[],
checked: [] as string[],
Expand Down Expand Up @@ -162,16 +169,20 @@ const getTables = () => {
fn.then((res = {}) => {
const data = res.items || []
const tables = data.map((it) => it.tableName)
const map = {}
const map: Record<string, TableMetadata> = {}
data.forEach((el = {}) => {
const {
tableName,
tableComment,
primaryKeyCounts = 0,
uniqueIndexCounts = 0,
meta_type,
} = el
if (tableComment || primaryKeyCounts || uniqueIndexCounts) {
map[tableName] = { tableComment, primaryKeyCounts, uniqueIndexCounts }
map[tableName] = {
tableComment,
primaryKeyCounts,
uniqueIndexCounts,
meta_type,
}
})
tableMap.value = map
Expand Down Expand Up @@ -416,6 +427,13 @@ getTables()
:enterable="false"
>
<span>
<ElIcon
v-if="getTableInfo(item).meta_type === 'view'"
class="align-icon-text mr-1 color-primary"
:size="14"
>
<i-lucide-eye />
</ElIcon>
<VIcon
v-if="!!getTableInfo(item).primaryKeyCounts"
size="12"
Expand Down Expand Up @@ -592,6 +610,13 @@ getTables()
:enterable="false"
>
<span>
<ElIcon
v-if="getTableInfo(item).meta_type === 'view'"
class="align-icon-text mr-1 color-primary"
:size="14"
>
<i-lucide-eye />
</ElIcon>
<VIcon
v-if="!!getTableInfo(item).primaryKeyCounts"
size="12"
Expand Down Expand Up @@ -622,6 +647,13 @@ getTables()
:content="errorTables[item]"
>
<div :class="{ 'color-danger': errorTables[item] }">
<ElIcon
v-if="getTableInfo(item).meta_type === 'view'"
class="align-icon-text mr-1 color-primary"
:size="14"
>
<i-lucide-eye />
</ElIcon>
<VIcon
v-if="!!getTableInfo(item).primaryKeyCounts"
size="12"
Expand Down Expand Up @@ -788,6 +820,7 @@ getTables()
overflow: hidden;
line-height: normal; // 微软雅黑下字符会溢出
}

}
.selector-center {
width: 46px;
Expand Down
2 changes: 1 addition & 1 deletion packages/dag/src/components/materialized-view/Node.vue
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ async function loadTable(filter, config) {
filter.where &&
Object.assign(filter.where, {
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ async function loadTable(
if (filter.where) {
Object.assign(filter.where, {
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand Down
15 changes: 13 additions & 2 deletions packages/dag/src/composables/useFetchConnections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ function calcMatchScore(name, keyword) {
return 0
}

interface TableListItem {
id: string
name: string
comment?: string
meta_type?: string
sourceName?: string
sourceId?: string
}

export function useFetchConnections() {
const pageSize = 20

Expand All @@ -41,7 +50,7 @@ export function useFetchConnections() {
items: [],
loading: false,
})
const tables = ref([])
const tables = ref<TableListItem[]>([])

const connectionsTotalPage = computed(() =>
Math.ceil(connectionsTotal.value / pageSize),
Expand Down Expand Up @@ -135,7 +144,7 @@ export function useFetchConnections() {
size: tableState.pageSize,
where: {
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
Expand All @@ -149,6 +158,7 @@ export function useFetchConnections() {
id: true,
source: true,
original_name: true,
meta_type: true,
},
// order: ['original_name ASC'],
}
Expand Down Expand Up @@ -189,6 +199,7 @@ export function useFetchConnections() {
id: tb.id,
name: tb.original_name,
comment: tb.comment,
meta_type: tb.meta_type,
sourceName: tb.source?.name,
sourceId: tb.source?.id,
}))
Expand Down
4 changes: 3 additions & 1 deletion packages/dag/src/composables/useFormScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,14 +480,15 @@ export function useFormScope({ canvasRef }) {
filter.where &&
Object.assign(filter.where, {
meta_type: {
in: ['collection', 'table'],
in: ['collection', 'table', 'view'],
},
is_deleted: false,
sourceType: 'SOURCE',
})
Object.assign(filter, {
fields: {
original_name: true,
meta_type: true,
},
order: ['original_name ASC'],
})
Expand All @@ -505,6 +506,7 @@ export function useFormScope({ canvasRef }) {
return {
label: item.original_name + (item.comment ? `(${item.comment})` : ''),
value: item.original_name,
meta_type: item.meta_type,
}
})
const table = filter.where.original_name?.like
Expand Down
Loading
Loading