showmore

show more style

import { apiAxios, showError } from '../../../js/portal/api';
import { removeDisabledOptions } from '../../../js/portal/main';
import swal from 'sweetalert';

/**
 * Creates a new selectpicker dropdown including a label and a refresh button. The dropdown list will be populated
 * automatically with all APP IDs from our caching DB.
 *
 * @param {string} label - name label on the left side of the dropdown menu
 * @param {string} id - the id of the selectpicker
 * @param {function} onchange - a function that will be triggered once the selectpicker value changes
 * @param {type[]} selectedValues - a list of app ids that should be selected if available
 * @param {boolean} deselect - defines if the deselect user button is added to the end of the selectpicker
 * @param {boolean} multiple - defines if you can select one or multiple items in the user dropdown
 * @param {boolean} disableUrlParams - by default, the component updates the query parameters for the current URL, "?email=<selectedOption>"
 * @param {boolean} ownUser - Whether BMW internal user email
 * 
 * @returns div including a label, the dropdown and a refresh button
 */
export default function AppDropdown({ label, id, onchange, selectedValues, deselect, multiple, disableUrlParams, ownUser }) {
  const selectId = id ? id : 'appDropdown';
  const disableParamsUpdate = disableUrlParams ? true : false;
  const headers = { 'Cache-Control': 'max-age=0, must-revalidate' };
  const params = {};

  // all app list data store
  let appDataStore = {}
  // 产品信息map
  let productMap = {}
  // 存储上一次选中的值
  let previousSelectedValues = [];


  // selectpicker options: https://developer.snapappointments.com/bootstrap-select/options/
  const select = (
    <select
      required
      class="form-control form-select selectpicker"
      data-live-search="true"
      data-show-subtext="true"
      id={selectId}
      name={selectId}
      data-size="10"
      data-max-options="5"
      data-none-selected-text="- Select one or more APP IDs -"
      data-selected-text-format="count > 1"
      data-count-selected-text="{0} Application(s) selected"
      data-dropdown-align-right="auto"
      multiple={multiple ? true : false}>
      <option class="defaultDisabled" value="" disabled selected={multiple ? false : true}>
        - Select one or more APP IDs -
      </option>
    </select>
  );

  // Refresh button to reload the user data
  const refreshIcon = <i class="fas fa-sync" />;
  const refreshButton = (
    <button
      type="button"
      class="btn btn-light-grey input-group-btn portal-selectpicker-end"
      id="refresh-users"
      title="Reload User List">
      {refreshIcon}
    </button>
  );

  // De-select button
  const deselectButton = (
    <button
      type="button"
      class="btn btn-light-grey input-group-btn portal-selectpicker-mid"
      id="deselect-users"
      title="De-select all users">
      <i class="fa fa-user-alt-slash" />
    </button>
  );

  // Represents the whole row including the label, the selectpicker and the refresh button
  const AppDropdown = (
    <div class="form-group row portal-dropdown">
      <div class="col input-group">
        {select}
        {deselect ? deselectButton : undefined}
        {refreshButton}
      </div>
    </div>
  );

  // Refresh the selectpicker and add an on change event
  $(select).selectpicker('refresh');


  // 修改 select 的 change 事件处理
  $(select).on('changed.bs.select', async (event, clickedIndex, isSelected, previousValue) => {
    /**
     * 1.event: jQuery 事件对象
     * 3.clickedIndex: 被点击的选项的索引值
     * 3.isSelected: 布尔值,true 表示选中,false 表示取消选中
     * 4.previousValue: 改变之前的值
     */
    console.log('Clicked index:', clickedIndex);
    console.log('Is selected:', isSelected);  // true 或 false
    console.log('Previous value:', previousValue);
    // 获取当前所有选中的值
    const currentSelectedValues = $(`#${selectId}`).val() || [];

    // 找出新增的值(当前选中的 appId)
    let currentAppId;
    if (isSelected) {
      // 如果是选中操作,找出新增的值
      currentAppId = $(select).find('option').eq(clickedIndex).val();
    } else {
      // 如果是取消选中操作,找出被移除的值
      currentAppId = previousSelectedValues.find(id => !currentSelectedValues.includes(id));
    }

    console.log('Current operation appId:', currentAppId);
    console.log('Is selected:', isSelected);

    // 获取当前操作的 app 完整信息
    const currentAppInfo = appDataStore[currentAppId];
    console.log('Current app info:', currentAppInfo);

    // 如果是选中操作,需要进行产品ID检查
    if (isSelected) {
      // EG 检查
      try {
        const isValidEG = await getTicketByAppIds(select, refreshIcon, currentAppId);
        if (!isValidEG) {
          return;
        }
      } catch (error) {
        showError(error);
        return;
      }
      // 检查是否是无产品ID的选项
      if (currentAppInfo && (!currentAppInfo.productId || currentAppInfo.productId === "product")) {
        // 如果是无产品ID的选项,强制单选
        $(select).selectpicker('deselectAll');
        $(`#${selectId} option[value="${currentAppId}"]`).prop('selected', true);
        $(select).selectpicker('refresh');
        previousSelectedValues = [currentAppId];
      } else {
        // 获取所有当前选中项的产品ID
        const selectedApps = currentSelectedValues.map(appId => appDataStore[appId]);
        const productIds = new Set(selectedApps.map(app => app.productId).filter(Boolean));

        // 如果产品ID数量大于1,说明不是同一个产品
        if (productIds.size > 1) {
          swal({
            title: 'Warning',
            text: 'The applications you have selected do not belong to the same product.',
            icon: 'warning',
            buttons: {
              okay: {
                text: 'OK',
                value: true,
                visible: true,
              },
            },
          }).then(() => {
            // 清空所有选择
            $(select).selectpicker('deselectAll');
            $(select).selectpicker('refresh');
            previousSelectedValues = [];

            // 如果需要,也可以触发 onchange 回调通知选择已清空
            if (onchange) {
              onchange({
                currentApp: null,
                isSelected: false,
                allSelectedApps: []
              });
            }
          });
          return; // 不继续执行后续代码
        }
      }


    }

    // 更新上一次的选中值
    previousSelectedValues = currentSelectedValues;


    // 调用回调函数,传递当前操作的 app 信息和选中状态
    if (onchange) {
      onchange({
        currentApp: currentAppInfo,
        isSelected: isSelected,
        allSelectedApps: currentSelectedValues.map(appId => appDataStore[appId])
      });
    }
  });

  // Reload the account records from the REST API (with cache-control headers)
  $(refreshButton).on('click', () => {
    getAppResponsibleRole(select, refreshIcon, selectedValues, multiple, disableParamsUpdate, headers, params);
  });

  // De-select all users from the selectpicker
  $(deselectButton).on('click', () => {
    $(select).selectpicker('deselectAll');
    $(select).selectpicker('refresh');
  });

  // Load the app list from the OPCP REST API (without cache-control headers)
  getAppResponsibleRole(select, refreshIcon, selectedValues, multiple, disableParamsUpdate, {}, {})

  /**
 * Get Application Responsible Role in ConnectIT.
 * Populates the selectpicker dropdown with the values from the REST API endpoint. 
 * Deletes all active dropdown items before adding the new items.
 * 
 *
 * @param {JSX.IntrinsicElements.select} select
 * @param {JSX.Element} refreshIcon
 * @param {type[]} selectedValues
 * @param {boolean} multiple
 * @param {object} headers
 * @param {object} params
 */

  function getAppResponsibleRole(select, refreshIcon, headers, params) {
    $(refreshIcon).addClass('fa-spin');
    $(select).attr('disabled', true).selectpicker('refresh');

    $(refreshIcon).addClass('fa-spin');
    $(select).attr('disabled', true).selectpicker('refresh');

    // 清空全局存储
    appDataStore = {};

    apiAxios
      .post('/opcp2/umps/app/getAppResponsibilitiesByUser', { headers, params })
      .then(async response => {
        removeDisabledOptions(select);
        const body = response.data.body;
        // body[0].productId = "SWP-1982"
        // 首先处理所有直接返回的应用
        body.forEach(item => {
          // 储存应用信息
          appDataStore[item.appId] = {
            appId: item.appId,
            appName: item.appName,
            productId: item.productId === "" ? "product" : item.productId,
            productName: item.productName || "Unknown",
            roles: item.roles
          };

          //存储产品信息
          if (item.productId) {
            productMap[item.productId] = {
              productId: item.productId,
              productName: item.productName,
            }
          }

        });

        // 收集非空的productIds
        const productIds = new Set();
        body.forEach(item => {
          if (item.productId) {
            productIds.add(item.productId);
          }
        });

        // 获取每个产品下的应用列表
        try {
          const productApps = await Promise.all(
            Array.from(productIds).map(async productId => {
              const response = await apiAxios.post('/opcp2/umps/app/getAppListByProduct', { productId })
              if(response.data.code==="200") {
                return response.data.body.map(app => ({
                  ...app,
                  appName: app.application,
                  productId: productId,
                  productName: productMap[productId]?.productName || "Unknown"
                }))
              }
            })
          );

          // console.log(productApps,'----productApps123----')

          // 合并产品下的应用列表
          if(productApps?.length) {
            console.log(productApps,'----productApps----')
            productApps.flat().forEach(app => {
              console.log(app,'----app----')
              if (!appDataStore[app.appId]) {
                appDataStore[app.appId] = {
                  appId: app.appId,
                  appName: app.appName,
                  productId: app.productId,
                  productName: app.productName
                };
              }
            });
          }

          // 更新下拉框选项
          const options = Object.values(appDataStore).map(item => {
            const opt = document.createElement('option');
            opt.value = item.appId;
            opt.innerText = `${item.appId}   ${item.appName}`;
            opt.setAttribute('data-subtext', item.productName || 'No Product');
            return opt;
          });

          // 清空并添加新选项
          $(select).find('option:not(.defaultDisabled)').remove();
          options.forEach(option => {
            select.appendChild(option);
          });

          // 如果有预选值,设置选中状态
          if (selectedValues && selectedValues.length) {
            selectedValues.forEach(value => {
              $(select).find(`option[value="${value}"]`).prop('selected', true);
            });
          }

          $(select).selectpicker('refresh');
        } catch (error) {
          showError(error);
        }
      })
      .catch(error => {
        showError(error);
      })
      .finally(() => {
        // Refresh the selectpicker to show the new options
        $(refreshIcon).removeClass('fa-spin');
        $(select).attr('disabled', false);
        $(select).selectpicker('refresh');
      });
  }
  return AppDropdown;

}


// 通过appid 获取对应EG infomation
function getTicketByAppIds(select, refreshIcon, appId) {
  return new Promise((resolve, reject) => {
    $(refreshIcon).addClass('fa-spin');
    $(select).attr('disabled', true).selectpicker('refresh');

    let params = {
      appIds: [appId]
    }
    let validEGCount = 0;
    apiAxios
      .post('/cloud/entryGateway/v1/GetTicketByAppIds', params)
      .then(response => {
        const data = response.data.body;
        if (data.length) {
          data.forEach(item => {
            if (item.platform === "TSP (AWS)" && item.entryStatus === 3) {
              ++validEGCount;
            }
          });

          if (validEGCount === 0) {
            swal({
              title: 'Warning',
              icon: 'warning',
              content: {
                element: "div",
                attributes: {
                  innerHTML: `There is no valid entry gateway record for ${appId}, please check your application's Entry Gateway status: (<a href="https://opcp.bmwgroup.net/prod/#/TSPCloud/EntryGateway" target="_blank">Entry Gateway</a>)`
                }
              },
              buttons: {
                okay: {
                  text: 'OK',
                  value: true,
                  visible: true,
                },
              },
            }).then(function (response) {
              $(`#appDropdown option[value="${appId}"]`).prop('selected', false);
              $(select).selectpicker('refresh');
              resolve(false); // EG 检查不通过
            });
          } else {
            resolve(true); // EG 检查通过
          }
        } else {
          swal({
            title: 'Warning',
            icon: 'warning',
            content: {
              element: "div",
              attributes: {
                innerHTML: `There is no valid entry gateway record for ${appId}, please check your application's Entry Gateway status: (<a href="https://opcp.bmwgroup.net/prod/#/TSPCloud/EntryGateway" target="_blank">Entry Gateway</a>)`
              }
            },
            buttons: {
              okay: {
                text: 'OK',
                value: true,
                visible: true,
              },
            },
          }).then(function (response) {
            $(`#appDropdown option[value="${appId}"]`).prop('selected', false);
            $(select).selectpicker('refresh');
            resolve(false); // EG 检查不通过
          });
        }
      })
      .catch(error => {
        showError(error);
        reject(error);
      })
      .finally(() => {
        $(refreshIcon).removeClass('fa-spin');
        $(select).attr('disabled', false);
        $(select).selectpicker('refresh');
      });
  });
}

11

Clicked index: 1
AppDropdown.jsx:103 Is selected: true
AppDropdown.jsx:104 Previous value: []
AppDropdown.jsx:118 Current operation appId: APP-26162
AppDropdown.jsx:119 Is selected: true
AppDropdown.jsx:123 Current app info: {appId: 'APP-26162', appName: 'TSP Cloud Platform', productId: 'product', productName: 'Unknown', roles: Array(2)}
AppDropdown.jsx:102 Clicked index: null
AppDropdown.jsx:103 Is selected: null
AppDropdown.jsx:104 Previous value: ['APP-26162']
AppDropdown.jsx:118 Current operation appId: undefined
AppDropdown.jsx:119 Is selected: null
AppDropdown.jsx:123 Current app info: undefined
OrderAdditionalPage.jsx:403 undefined null [] '-----回调事件'
OrderAdditionalPage.jsx:403 {appId: 'APP-26162', appName: 'TSP Cloud Platform', productId: 'product', productName: 'Unknown', roles: Array(2)} true [{…}] '-----回调事件'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值