Skip to content

Commit 623a6f9

Browse files
committed
feat: add repository guidelines for icon usage and TypeScript validation; update components to support 'view' meta_type
1 parent e7b4c7b commit 623a6f9

20 files changed

Lines changed: 152 additions & 28 deletions

File tree

AGENTS.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Repository Guidelines
2+
3+
## Icons
4+
5+
- Prefer Lucide icons when adding or replacing icons. Do not use Element Plus icons when a suitable Lucide icon exists.
6+
- Lucide icons are auto-imported; do not add manual imports for them.
7+
- In Vue templates, use kebab-case components with the `i-lucide-` prefix, for example `<i-lucide-eye />`.
8+
- In TSX templates, use the auto-imported `ILucide` PascalCase component name, for example `<ILucideEye />`.
9+
- 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}`.
10+
- Except inside an `el-button`/`ElButton` icon slot, wrap rendered Lucide icons with `el-icon`/`ElIcon`.
11+
- 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.
12+
- Inside an `el-button`/`ElButton` icon slot, the Lucide component may be used directly because the button provides the icon wrapper and sizing context.
13+
14+
## TypeScript and Validation
15+
16+
- Parts of the existing codebase intentionally lack complete TypeScript typing. Do not expand the task to retrofit types in unrelated existing code.
17+
- Add reasonable, focused types for newly introduced TypeScript/TSX code and for existing declarations that must change to support the new code.
18+
- 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.
19+
- Prefer targeted inspection or lightweight checks when validation is useful, without treating unrelated existing type errors as part of the task.

packages/assets/styles/utilities.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@
272272
vertical-align: text-top !important;
273273
}
274274

275+
.align-icon-text {
276+
vertical-align: -0.125em !important;
277+
}
278+
275279
.float-start {
276280
float: left !important;
277281
}
@@ -13241,4 +13245,4 @@
1324113245

1324213246
.text-amber-500 {
1324313247
color: oklch(76.9% 0.188 70.08);
13244-
}
13248+
}

packages/dag/src/components/LeftSidebar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ export default {
286286
'source.id': this.activeConnection.id,
287287
taskId: this.$store.state.dataflow.taskId,
288288
meta_type: {
289-
in: ['collection', 'table'],
289+
in: ['collection', 'table', 'view'],
290290
},
291291
is_deleted: false,
292292
sourceType: 'SOURCE',

packages/dag/src/components/NodesPanel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ const handleFetchTables = async () => {
158158
size: tableState.pageSize,
159159
where: {
160160
meta_type: {
161-
in: ['collection', 'table'],
161+
in: ['collection', 'table', 'view'],
162162
},
163163
is_deleted: false,
164164
sourceType: 'SOURCE',

packages/dag/src/components/elements/NodesPopover.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,10 @@ defineExpose({
693693
<div
694694
class="flex align-center justify-center p-1.5 bg-gray-100 dark:bg-white/15 rounded-lg"
695695
>
696-
<el-icon :size="16"><i-lucide-table /></el-icon>
696+
<el-icon :size="16">
697+
<i-lucide-eye v-if="item.meta_type === 'view'" />
698+
<i-lucide-table v-else />
699+
</el-icon>
697700
</div>
698701

699702
<div>
@@ -732,7 +735,10 @@ defineExpose({
732735
class="flex h-8 align-center gap-2 px-3 connection-item rounded-lg user-select-none"
733736
@click="onClickTable(item)"
734737
>
735-
<el-icon :size="16"><i-lucide-table /></el-icon>
738+
<el-icon :size="16">
739+
<i-lucide-eye v-if="item.meta_type === 'view'" />
740+
<i-lucide-table v-else />
741+
</el-icon>
736742
<OverflowTooltip
737743
class="text-truncate"
738744
:text="item.name"

packages/dag/src/components/form/load-schema-tree/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export const loadSchemaTree = observer(
9191
where: {
9292
'source.id': connectionId,
9393
meta_type: {
94-
in: ['collection', 'table'],
94+
in: ['collection', 'table', 'view'],
9595
},
9696
is_deleted: false,
9797
sourceType: 'SOURCE',

packages/dag/src/components/form/table-list-card/index.tsx

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ import { getPrimaryKeyTablesByType } from '../../../util'
1313
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
1414
import './style.scss'
1515

16+
interface TableMetadata {
17+
tableName: string
18+
tableComment?: string
19+
primaryKeyCounts?: number
20+
uniqueIndexCounts?: number
21+
meta_type?: string
22+
}
23+
24+
interface TableListItem {
25+
tableName: string
26+
}
27+
1628
export const TableListCard = observer(
1729
defineComponent({
1830
props: [
@@ -26,9 +38,10 @@ export const TableListCard = observer(
2638
],
2739
setup(props) {
2840
const loading = ref(false)
29-
const list = ref([])
41+
const list = ref<TableListItem[]>([])
3042
const total = ref(0)
31-
const tableMap = ref({})
43+
const tableNames = ref<string[]>([])
44+
const tableMap = ref<Record<string, TableMetadata>>({})
3245

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

4457
fn.then((data) => {
45-
const map = {}
46-
const items = data?.items || []
58+
const map: Record<string, TableMetadata> = {}
59+
const items: TableMetadata[] = data?.items || []
4760
items.forEach((t) => {
48-
if (t.uniqueIndexCounts || t.primaryKeyCounts) {
49-
map[t.tableName] = t
50-
}
61+
map[t.tableName] = t
5162
})
5263
tableMap.value = map
64+
tableNames.value = items.map((t) => t.tableName)
5365
list.value = getPrimaryKeyTablesByType(
54-
items.map((t) => t.tableName) || [],
66+
tableNames.value,
5567
props.filterType,
5668
tableMap.value,
5769
).map((tableName) => ({ tableName }))
@@ -65,7 +77,7 @@ export const TableListCard = observer(
6577
() => props.filterType,
6678
() => {
6779
list.value = getPrimaryKeyTablesByType(
68-
list.value.map((t) => t.tableName) || [],
80+
tableNames.value,
6981
props.filterType,
7082
tableMap.value,
7183
).map((tableName) => ({ tableName }))
@@ -93,8 +105,13 @@ export const TableListCard = observer(
93105
placement="right"
94106
open-delay={400}
95107
>
96-
<span>
97-
<span class="align-middle">{name}</span>
108+
<span class="flex align-center">
109+
{tableMap.value[name]?.meta_type === 'view' && (
110+
<el-icon size={14} class="mr-1 color-primary">
111+
<ILucideEye />
112+
</el-icon>
113+
)}
114+
<span>{name}</span>
98115
{tableMap.value[name]?.tableComment && (
99116
<span class="font-color-sslight align-middle">{`(${tableMap.value[name].tableComment})`}</span>
100117
)}

packages/dag/src/components/form/table-list-card/style.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929
white-space: nowrap;
3030
overflow: hidden;
3131
text-overflow: ellipsis;
32+
33+
.table-list-view-icon {
34+
color: color-mix(
35+
in srgb,
36+
var(--el-text-color-secondary) 72%,
37+
var(--color-primary)
38+
);
39+
}
40+
3241
&:hover {
3342
background-color: var(--fill-hover);
3443
}

packages/dag/src/components/form/table-select/index.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,20 @@ export const TableSelect = connect(
279279
{i18n.t('public_data_no_data')}
280280
</p>
281281
),
282+
option: ({ item }) => {
283+
return (
284+
<span class="inline-flex align-center gap-2">
285+
<el-icon size={16}>
286+
{item.meta_type === 'view' ? (
287+
<i-lucide-eye />
288+
) : (
289+
<i-lucide-table />
290+
)}
291+
</el-icon>
292+
<span>{item.value}</span>
293+
</span>
294+
)
295+
},
282296
}
283297

284298
if (props.allowCreate) {

packages/dag/src/components/form/table-selector/TableSelector.vue

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
1818
const dataflowStore = useDataflowStore()
1919
const { t } = useI18n()
2020
21+
interface TableMetadata {
22+
tableComment?: string
23+
primaryKeyCounts?: number
24+
uniqueIndexCounts?: number
25+
meta_type?: string
26+
}
27+
2128
// Props
2229
const props = defineProps({
2330
connectionId: {
@@ -51,7 +58,7 @@ const isOpenClipMode = ref(false)
5158
const isFocus = ref(false)
5259
const clipboardValue = ref('')
5360
const errorTables = ref({})
54-
const tableMap = ref({})
61+
const tableMap = ref<Record<string, TableMetadata>>({})
5562
const table = ref({
5663
tables: [] as string[],
5764
checked: [] as string[],
@@ -162,16 +169,20 @@ const getTables = () => {
162169
fn.then((res = {}) => {
163170
const data = res.items || []
164171
const tables = data.map((it) => it.tableName)
165-
const map = {}
172+
const map: Record<string, TableMetadata> = {}
166173
data.forEach((el = {}) => {
167174
const {
168175
tableName,
169176
tableComment,
170177
primaryKeyCounts = 0,
171178
uniqueIndexCounts = 0,
179+
meta_type,
172180
} = el
173-
if (tableComment || primaryKeyCounts || uniqueIndexCounts) {
174-
map[tableName] = { tableComment, primaryKeyCounts, uniqueIndexCounts }
181+
map[tableName] = {
182+
tableComment,
183+
primaryKeyCounts,
184+
uniqueIndexCounts,
185+
meta_type,
175186
}
176187
})
177188
tableMap.value = map
@@ -416,6 +427,13 @@ getTables()
416427
:enterable="false"
417428
>
418429
<span>
430+
<ElIcon
431+
v-if="getTableInfo(item).meta_type === 'view'"
432+
class="align-icon-text mr-1 color-primary"
433+
:size="14"
434+
>
435+
<i-lucide-eye />
436+
</ElIcon>
419437
<VIcon
420438
v-if="!!getTableInfo(item).primaryKeyCounts"
421439
size="12"
@@ -592,6 +610,13 @@ getTables()
592610
:enterable="false"
593611
>
594612
<span>
613+
<ElIcon
614+
v-if="getTableInfo(item).meta_type === 'view'"
615+
class="align-icon-text mr-1 color-primary"
616+
:size="14"
617+
>
618+
<i-lucide-eye />
619+
</ElIcon>
595620
<VIcon
596621
v-if="!!getTableInfo(item).primaryKeyCounts"
597622
size="12"
@@ -622,6 +647,13 @@ getTables()
622647
:content="errorTables[item]"
623648
>
624649
<div :class="{ 'color-danger': errorTables[item] }">
650+
<ElIcon
651+
v-if="getTableInfo(item).meta_type === 'view'"
652+
class="align-icon-text mr-1 color-primary"
653+
:size="14"
654+
>
655+
<i-lucide-eye />
656+
</ElIcon>
625657
<VIcon
626658
v-if="!!getTableInfo(item).primaryKeyCounts"
627659
size="12"
@@ -788,6 +820,7 @@ getTables()
788820
overflow: hidden;
789821
line-height: normal; // 微软雅黑下字符会溢出
790822
}
823+
791824
}
792825
.selector-center {
793826
width: 46px;

0 commit comments

Comments
 (0)