vue3项目 使用 element-plus 中 el-collapse 折叠面板

最近接触拉了一个项目,使用到 element-plus 中 el-collapse 折叠面板,发现在使用中利用高官网多多少少的会出现问题。
(1.直接默认一个展开值,发现时显时不显
2 . 数据渲染问题,接口请求了,页面数据不更新
3 样式问题,自定义表头title等等)
我们的数据结构是双数组,如果你和我一样直接copy, 如果是一个对象数组或者数组吧,只需把外层的数组转化即可
在这里插入图片描述

效果图 : 当点击 了查看按钮时,弹框出现,且默认展开第一个数据,且每次的展开或者收起都有对应的样式,可见下图左侧的图样,
我这里还用到了 el-steps ,最外层的 是自己写的样式,因为我一个页面中使用了两次el-steps ,发现样式会有干扰。所以我在最外层的el-steps是自己写的div标签。

注意 的是我们使用 官网说明的 const activeName = ref([]) 数组类型 ,且里面的值使用字符串类型。
当 弹框出现时,调用接口进行处理赋值 activeName,并转成 toString() 字符串,然后默认展开第一项
	activeName.value.push(index.toString())
    activeName.value = ['0']
    在进行处理每个item之间的高和选中样式。
    最后在处理点击@change 的事件
    
    // 处理在展开折叠状态
	const handleCollapseChange = (val: any) => {
	  // console.log(val, 'val');
	  PurchaseInfo.forEach((item:any, index:any)=>{
	    if(val){
	      if(val === index.toString()){
	        item.flagActive = true
	        item.height = myCollapseRef.value.$el.clientHeight + 20
	      } else{
	        item.flagActive = false
	        item.height = 38
	      }
	    }else{
	      item.flagActive = false
	      item.height = 38
	    }
	  })
	  // console.log(PurchaseInfo, 'PurchaseInfo')
	}

在这里插入图片描述
上代码了。

<ProcessViewDialog
  v-model:value="dialogFormVisible"
  :projectDeviceId="projectDeviceId"
/>

自己 引入组件

<template>
  <div>
    <zmjDialog
      v-model="show"
      width="460"
      @opened="init"
      title="查看所有设备"
      center
    > 
      <div style="display:flex; width: 460px">
        <div class="el-dialog-div">
          <div class="el-dialog_divleft">
            <div class=divleftlast v-for="(el, index) in PurchaseInfo" :key="index">
              <p :class="el.flagActive ? 'arrdata1Active' : 'arrdata1'"></p>
              <p :style="{width: 2 + 'px', height: el.height + 'px', background: '#E8F0FF', borderRadius: '0px 0px 0px 0px', marginLeft: '8px'}"></p>
            </div>
          </div>
          <el-collapse
            class="el-collapse-parent"
            v-model="activeName"
            accordion
            @change="handleCollapseChange"
            ref="myCollapseRef"
          >
            <el-collapse-item
              v-for="(item, index) in PurchaseInfo"
              :key="index"
              :name="index.toString()"
              style="margin-bottom: 10px;"
              ref="itemHeight"
            >
              <template #title>
                <div :class="item.flagActive ? 'headerRightTrue' : 'headerRightFlase'">
                  <span class="spanFalse"></span>
                  <div class="itemApproveTimeFalse">
                    {{ item.approveTime }}
                  </div>
                  <div class="top-right">
                    <div> {{item.operatorName}} <span v-if="item?.nodeId"> ({{item?.nodeId == 120 ? '方案' : ( item?.nodeId == 130 ? '商务活动' : (item?.nodeId == 140 ? '配套' : '' ))}}) </span> </div>
                    <span :class="item.flagActive ? 'headerRightspan1' : 'headerRightspan2'">{{ activeName.includes(index.toString()) ? '收起' : '展开' }}</span>
                  </div>
                </div>
              </template>
              <div class="contntDiv">
                <div class="contntDiv-1">
                  <div class="contntDiv-1">
                    <span class="contntDiv-1-span"> {{item.model}} </span>
                    <span class="contntDiv-2-span"> {{ item?.supportLabel === 1 ? '标准架型' : (item?.supportLabel === 3 ? '模块架型' : '非标架型')}} </span>
                  </div>
                  <div class="contntDiv-1-d"> {{ item?.deviceCount}}架 </div>
                </div>
                <div class="line"></div>
                <div>
                  <div class="contntDiv-item-left"> 片区 </div>
                  <div class="contntDiv-item-right"> {{ item?.areaName }} </div>
                </div>
                <div>
                  <div class="contntDiv-item-left"> 支架类型 </div>
                  <div class="contntDiv-item-right"> {{ GET_SUPPORT_TYPE(item?.firstDeviceType) }} - {{ GET_SUPPORT_SECOND_TYPE_NAME(item?.secondDeviceType) }}</div>
                </div>
                <div>
                  <div class="contntDiv-item-left"> 图号 </div>
                  <div class="contntDiv-item-right"> {{item?.standardGroupNo }} </div>
                </div>
                <div>
                  <div class="contntDiv-item-left"> 单架重量 </div>
                  <div class="contntDiv-item-right"> {{ item?.singleWeight}}吨 </div>
                </div> 
                <div>
                  <div class="contntDiv-item-left"> 支架特征代号 </div>
                  <div class="contntDiv-item-right"> {{ joinSupportFeatureModel }} </div>
                </div>
                <div class="contntDiv-item-right-bottom" v-if="item?.supportFeatureModel && item?.supportFeatureModel?.length > 0">
                  *支架产品型号{{ item?.supportProductModel}}
                </div>
              </div>
              <div class="box-approve" v-if="item?.flowApproveDtoList?.length>0">
                <el-steps direction="vertical" :active="1" align-center>
                  <el-step v-for="(v, i) in item?.flowApproveDtoList" class="my-text" :key="i">
                    <template #icon>
                      <div class="titleDiv">
                        <div class="time">{{ v.updateTime }}</div>
                      </div>
                    </template>
                    <template #title>
                      <div class="step-icon"></div>
                    </template>
                    <template #description>
                      <div class="descriptionDiv">
                        <div style="color: #707070; font-size: 14px">
                        <span class="" style="color: #3076fe">{{ v.approveUserName }}</span>
                        <!-- approveType  1 提交 2 审批 status 1 未审批 2  审批通过 3 驳回 -->
                        <span v-if="v.approveType == 1 && v.status == 2 && isLastElement(item?.flowApproveDtoList, i)" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #262626">提交审批</span></span>
                        <span v-else>
                          <span v-if="v.approveType == 1 && v.status == 2" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #262626">再次提交审批</span></span>
                          <span v-if="v.approveType == 1 && v.status == 3" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #ffb236">审批驳回</span></span>
                          <span v-if="v.approveType == 2 && v.status == 2">
                            <span style="color: #63af17">审批通过</span>
                          </span>
                          <span v-if="v.approveType == 2 && v.status == 3">
                            将<span style="color: #ffb236">审批驳回</span>
                          </span>
                        </span>
                        </div>
                        <div v-if="(v.approveType == 1 || v.approveType == 2) && v.status == 3" class="reject-box">
                          <div class="reject-item-1">
                            <div>驳回原因</div>
                            <div>{{ v.rejectReason }}</div>
                          </div>
                        </div>
                      </div>
                      
                    </template>
                  </el-step>
                </el-steps>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="show = false">返回</el-button>
        </div>
      </template>
    </zmjDialog>
  </div>
</template>


<script setup lang="ts">
import { recordLog } from '@/api/project/device' // 接口替换为完成
import { GET_SUPPORT_TYPE, GET_SUPPORT_SECOND_TYPE_NAME } from './config'
const props = defineProps({
  dialogFormVisible: Boolean,
  value: Boolean,
  projectDeviceId: { type: Number, default: null }, // 业务id
})
// const activeName = ref()
const activeName = ref([])
const emit = defineEmits(['update:value', 'exit'])
// 添加页面弹出标识
let show = computed({
  get() {
    return props.value
  },
  set(val: any) {
    emit('update:value', val)
  }
})
let PurchaseInfo:any = reactive([])
let joinSupportFeatureModel:any = ref('')

// 判断数组的最后一个
const isLastElement = (array:any, index:any) => {
  return index === array.length - 1
}

const init = async () => {
  try {
    const res: any = await recordLog({ deviceId: props.projectDeviceId })
    PurchaseInfo = res.data
    let arr:any = []
    activeName.value = []
    PurchaseInfo.forEach((item:any, index:any)=>{
      activeName.value.push(index.toString())
      activeName.value = ['0']
      if(index.toString() === activeName.value[0]){
        item.height = myCollapseRef.value.$el.clientHeight + 20
        item.flagActive = true
      }else{
        item.height = 38
        item.flagActive = false
      }
      item?.supportFeatureModel?.map((v:any)=>{
        if(v==='A1'){
          arr.push('A类支架')
        } else if(v ==='Q'){
          arr.push('大倾角')
        }else if(v ==='D'){
          arr.push('电液控')
        }else if(v ==='A'){
          arr.push('大侧帮支架左架')
        }else if(v ==='B'){
          arr.push('大侧帮支架右架')
        }else{
          arr = []
        }
      })
    })
    // console.log(PurchaseInfo, 'PurchaseInfo-loading---',)
    joinSupportFeatureModel.value = arr.join('、')
  } catch (err) {
    console.log(err.message)
  }
}

let myCollapseRef = ref()
const itemHeight = ref(null)
// 监听折叠状态
const handleCollapseChange = (val: any) => {
  // console.log(val, 'val');
  PurchaseInfo.forEach((item:any, index:any)=>{
    if(val){
      if(val === index.toString()){
        item.flagActive = true
        item.height = myCollapseRef.value.$el.clientHeight + 20
      } else{
        item.flagActive = false
        item.height = 38
      }
    }else{
      item.flagActive = false
      item.height = 38
    }
  })
  // console.log(PurchaseInfo, 'PurchaseInfo')
}
</script>

<style lang="scss" scoped>
.el-dialog_divleft{
  width: 10px;
  // margin-left: 10px;
  margin-top:28px;
  display: flex;
  flex-wrap: wrap;
  height: 38px;
}
/* 选择最后一个div中的第二个p标签,并应用样式 */
.divleftlast:last-child p:last-child {
  display: none;
}
.arrdata1{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid #3076fe;
  // margin-top: 15px;
  margin-left: 5px;
}
.arrdata1Active{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid #3076fe;
  // margin-top: 15px;
  margin-left: 5px;
  background: #3076fe;
}
.el-dialog-div {
  // width: 395px;
  width: 100%;
  margin-left: 20px; // 20px
  height: 50vh;
  overflow-x: hidden;
  display: flex;
}

.page-content {
  padding: 24px 44px;
  .device-group {
    &:not(:first-child) {
      margin-top: 12px;
    }
  }
  :deep(.el-descriptions.zmj-descriptions) {
    .el-descriptions__header {
      margin-top: 12px;
      margin-bottom: 8px;
      .el-descriptions__title {
        font-weight: 400;
      }
    }

    .el-descriptions__cell {
      padding: 10px 12px;
      color: #262626;
    }
    .el-descriptions__label {
      padding: 10px 12px;
      background-color: #fafafa;
      color: #707070;
    }
  }
}
.page-empty {
  height: 100%;
}
.color-centent {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: #3076fe;
}
/* 如果您想要在展开的el-collapse-item上添加特殊样式,可以使用深度选择器 */
.el-collapse {
  :deep(.el-collapse-item__content) {
    border: 1px solid #3076FE;
    padding-bottom: 0px; /* 根据需要调整padding值 */
    width: 384px;
  }
}

.el-collapse-parent{
  margin-top: 10px;
  border: none;
  width:395px;
  margin-left: 10px;
  :deep(.el-collapse-item__header){
    background: #3076FE;
    border-radius: 4px 4px 0px 0px;
    width: 384px;
    height: 39px
  }
}
:deep(.el-collapse-item__arrow){
  display:none;
}
.headerRightTrue{
  width: 395px;
  height: 38px;
  background: #3076FE;
  border-radius: 4px 4px 0px 0px;
  display: flex;
  justify-content: space-between;
  padding: 10px;
  color:#fff;
  font-size: 14px;
  line-height: 20px;
  top: -20px;
  .top-right{
    width: 160px;
    display: flex;
    // justify-content: space-around;
    justify-content: space-between;
    font-size: 12px;
    .headerRightspan1{
      color:#fff;
    }
  }
}
.spanFalse{
    width: 4px;
    height: 12px;
    background: #3076FE;
    border-radius: 0px 0px 0px 0px;
    margin-top: 4px;
  }
  .itemApproveTimeFalse{
    margin-left: -55px;
  }
.headerRightFlase{
  background: #F3F8FF;
  width: 395px;
  height: 38px;
  border-radius: 4px 4px 0px 0px;
  display: flex;
  justify-content: space-between;
  padding: 10px;
  color: #666666;
  font-size: 14px;
  line-height: 20px;
  top: -20px;
  border: 1px solid #3076FE;
  .top-right{
    width: 160px;
    display: flex;
    // justify-content: space-around;
    justify-content: space-between;
    font-size: 12px;
    .headerRightspan2{
      color: #3076FE
    }
  }
}
.contntDiv{
  width: 355px;
  height: 200px;
  background: #F3F8FF;
  border-radius: 4px 4px 4px 4px;
  border: 1px solid #EEEEEE;
  padding: 10px;
  // margin: 14px;
  margin: 8px 14px;
  >div{
    display: flex;
    justify-content: space-between;
    margin-top: 5px;
  }
  .contntDiv-1-span{
    width: 116px;
    height: 20px;
    font-size: 14px;
    color: #262626;
    line-height: 0px;
    text-align: left;
  }
  .contntDiv-2-span{
    font-size: 10px;
    color: #1890FF;
    text-align: center;
    height: 16px;
    background: #E3F2FF;
    border-radius: 2px 2px 2px 2px;
    margin-left: 14px;
  }
  .contntDiv-1-d{
    height: 17px;
    font-size: 12px;
    color: #A3A3A3;
  }
  .line{
    background: #F3F8FF;
    border: 1px dotted #A3A3A3;
  }
  .contntDiv-item-left{
    // width: 100px;
    height: 18px;
    font-size: 13px;
    color: #A3A3A3;
  }
  .contntDiv-item-right{
    // width: 112px;
    height: 18px;
    font-size: 13px;
    color: #262626;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .contntDiv-item-right-bottom{
    height: 18px; 
    font-size: 13px;
    color: #262626;
    text-align: left;
    display: flex;
    justify-content: flex-end;
  }
}

.box-approve {
  min-height: 130px;
  max-height: calc(100% - 82px);
  overflow: auto;
  margin-top: -5px;
}
.step-icon {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #A3A3A3;
  border: 1px solid #A3A3A3;
  margin-left: 50px;
  // margin-top: 0px;
}
.titleDiv{
  display: flex;
  width: 155px;
  .time {
    color: #c2c2c2;
    font-size: 12px;
    margin-left: 90px;
    width: 100px;
  }
}

:deep(.el-steps) {
  height: 100%;
}
:deep(.el-step__line){
  background: #E8F0FF;
  border: 1px dotted #A3A3A3;
  margin-left: 87px;
  margin-top: 20px;
  height: calc(100% - 20px);
}
:deep(.el-step__main) {
  padding: 8px 8px 9px;
  // background-color: #f1f6ff;
  min-height: 58px;
  box-sizing: border-box;
  margin-bottom: 12px;
  .el-step__description {
    font-size: 14px;
  }
}
:deep(.el-step__title){
  margin-left: 11px;
  color: #e0e0e0;
}
// :deep(.el-step__head){
//   // margin-left:110px;
// }
.reject-box {
  font-size: 12px;
  color: #a3a3a3;
  .reject-item-1 {
    display: flex;
    & > div:nth-child(1) {
      flex-shrink: 0;
    }
    & > div:nth-child(2) {
      word-break: break-word;
      width: 100%;
    }
  }
}
.descriptionDiv{
  height: 100%;
  width: 264px;
  margin-left: 76px;
  margin-top: -20px;
}
</style>

完成,请指教
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/548654.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通过Omnet++官网tictoc教程学习在Omnet++中构建和运行仿真 Part3

TicToc Part3 增强2节点 TicToc增加图标增加 日志添加状态变量增加参数使用NED 继承模拟处理延时随机数字和参数超时、取消计时器重传同样的消息 官方文档 在官方文档中&#xff0c;你可以看见所有的代码 增强2节点 TicToc 增加图标 为了使模型在GUI中看起来更好看&#xff…

计算机网络—TCP协议详解:协议构成、深度解析(1)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 3:34 &#x1f504; ◀️…

vs2008使用 openmp

目录 1 在项目中找到property pages>>c/c>>language>>openmp支持 2 在环境变量中增加“OMP_NUM_THREADS”变量&#xff0c;数值自己根据你的CPU的性能来设置&#xff0c;一般2、4、8等 3 在项目中输入如下代码&#xff0c;并编译运行 4 结果与不使用omp的…

浅谈Java IO流

Java中的IO流&#xff08;Input/Output streams&#xff09;是Java程序用来处理数据输入和输出的核心工具集。IO流抽象了数据流动的概念&#xff0c;允许Java程序与外部世界进行数据交换&#xff0c;无论是从文件、网络、键盘输入还是向屏幕、文件或网络发送数据。Java IO流按照…

RAG 如何消除大模型幻觉

什么是大模型幻觉 假设我们有一个基于大型生成模型&#xff08;如GPT-3&#xff09;的问答系统&#xff0c;该系统用于回答药企内部知识库中的问题。我们向其提出一个问题&#xff1a;“阿司匹林的主要药理作用是什么&#xff1f;” 正确的答案应该是&#xff1a;“阿司匹林主…

Qt 的内存管理机制

目录 Qt 的内存管理机制 Qt 的对象树 利用代码查看自动释放 Qt 的内存管理机制 Qt 的对象树 Qt 中所有的控件都是被一颗多叉树管理起来的&#xff0c;这样就是为了方便释放资源的时候方便释放&#xff0c;而我们在编写代码的时候&#xff0c;创建对应的控件&#xff0c;然…

Samtec科普 | 一文入门连接器电镀的QA

【摘要/前言】 像大多数电子元件一样&#xff0c;无数子元件和工艺的质量直接影响到成品的质量和性能。对于PCB级连接器&#xff0c;这些因素包括针脚材料、塑料类型、模制塑料体的质量、尾部的共面性、表面处理&#xff08;电镀&#xff09;的质量、选择正确的连接器电镀、制…

【C++算法模板】数论:欧拉筛,线性查找质数的算法

文章目录 1&#xff09;传统找质数的方法&#xff08;优化筛选次数&#xff09;2&#xff09;欧拉筛 1&#xff09;传统找质数的方法&#xff08;优化筛选次数&#xff09; bool isPrime(int num) {for(int i2;i<sqrt(num)) {if(num%i0)return false;}return true; }如果要…

跑马拉松跑成骨坏死?!马拉松赛事密集,提前了解运动损伤很重要

跑步狂热者右脚疼痛未重视 日积月累右脚终于“撑”不住了 近日&#xff0c;徐大爷来院就诊说自己半年前右脚莫名出现酸痛&#xff0c;一直没当回事&#xff0c;结果1个月前跑完步疼痛加重&#xff0c;最近严重到影响日常走路&#xff0c;无奈只能找医生。在医生的详细检查和认真…

基于arduino的ESP32上蓝牙midi音乐设备开发教程

目录 简介 开发环境 开发过程 函数介绍 相关文章 简介 首先看几个视频&#xff0c;大佬们做的东西&#xff0c;都是基于esp32。 自制卡林巴电子琴&#xff0c;可通过蓝牙连接手机库乐队 MIDI Boy【理科生的第一件乐器】_哔哩哔哩_bilibili 【Totoro】模仿“埙”的电子吹…

win11电脑驱动怎么更新,windows11更新驱动

驱动是指计算机里软件的程序,硬件的运作离不开驱动的支持,因为驱动就是使得硬件和电脑系统沟通的桥梁。既然驱动如此重要,那么不装肯定不行,如果有问题,也要及时地修复和更新。最近,有位win11用户,想要了解win11电脑驱动怎么更新?接下来,教程会带来两种更新win11驱动的…

vscode i18n Ally插件配置项

.vscode文件&#xff1a; {"i18n-ally.localesPaths": ["src/lang"], //显示语言&#xff0c; 这里也可以设置显示英文为en,// 如下须要手动配置"i18n-ally.keystyle": "nested", // 翻译路径格式 (翻译后变量格式 nested&#xff1a…

[C++初阶]类和对象(一)

1.面向过程和面向对象的区分 我们之前都是用C语言写的代码,我们知道C语言是一个面向过程的语言,但是现在我们学的时C,我们都知道C是一种面向对象的语言,那么什么叫面向过程?什么叫面向对象呢? 这里我们来举个例子: 比如我们是开饭店的&#xff0c;客人点了一道菜&#xff0c…

开源模型应用落地-LangChain试炼-CPU调用QWen1.5(一)

一、前言 尽管现在的大语言模型已经非常强大&#xff0c;可以解决许多问题&#xff0c;但在处理复杂情况时&#xff0c;仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而&#xff0c;现在可以利用langchain来使得模型的应用变得更加直接和简单。 通过langchain框…

什么是T型槽铸铁平板中内应力——河北北重厂家

T型槽铸铁平板中的内应力指的是平板内部受到的内部力&#xff0c;包括拉应力和剪应力。在T型槽铸铁平板使用过程中&#xff0c;由于自身重量、外力加载等原因&#xff0c;会产生内部应力。这些内应力是平板内部各部分之间的相互作用力&#xff0c;使得平板各部分受到不同的拉伸…

C++ 为什么不能在构造函数中调用虚函数

最近在Clion编辑器中看到构造函数中调用虚函数提示&#xff1a; Do not invoke virtual member functions from constructor 这里记录一下为什么不能在构造函数中调用虚函数。 #include <iostream> #include <string>using namespace std;class BaseClass {publi…

大模型时代:普通人该如何获利?

随着科技的飞速发展&#xff0c;我们正处在一个大模型的时代。所谓大模型&#xff0c;就是指那些拥有数十亿、甚至千亿参数的深度学习模型。这些大模型的出现&#xff0c;不仅推动了人工智能技术的进步&#xff0c;也为普通人创造了众多的获利机会。那么&#xff0c;在这个大模…

【Java开发指南 | 第六篇】Java成员变量(实例变量)、 类变量(静态变量)

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 成员变量&#xff08;实例变量&#xff09;类变量&#xff08;静态变量&#xff09;定义方式静态变量的使用场景 成员变量&#xff08;实例变量&#xff09; 成员变量声明在一个类中&#xff0c;但在方法、构造…

GAMS104 现代游戏引擎 2

渲染的难点可以分为一下三部分&#xff1a;如何计算入射光线、如何考虑材质以及如何实现全局光照。 渲染的难点之一在于阴影&#xff0c;或者说是光的可见性。如何做出合适的阴影效果远比想象中要难得多&#xff0c;在实践中往往需要通过大量的技巧才能实现符合人认知的阴影效…

AI数字人对话之RealChar框架源码解读

零.功能介绍 与虚拟角色(非形象)进行文本或语音会话 体验地址:RealChar. 代码库:GitHub - Shaunwei/RealChar: 🎙️🤖Create, Customize and Talk to your AI Character/Companion in Realtime (All in One Codebase!). Have a natural seamless conversation with AI…