1{"version":3,"file":"TeamList.0e38943fa459e872fe93.js","mappings":"8vBAKO,MAAMA,EAAqB,CAQhCC,EACAC,EACAC,IACIC,IACJ,MAAMC,GAAqBC,EAAAA,EAAAA,SACzBL,EACAC,EAFyBI,CAIzBF,GAEIG,EAAoDC,IACxD,MAAMC,GAAWC,EAAAA,EAAAA,eAOjB,OANAC,EAAAA,EAAAA,YAAU,IACD,WACLF,GAASG,EAAAA,EAAAA,GAAc,CAAET,cAAAA,OAE1B,CAACM,KAEG,SAACJ,EAAD,iBAAwBG,KAOjC,OAJAD,EAA8BM,YAAe,sBAAqBR,EAAmBQ,eACrFC,GAAAA,CAAqBP,EAA+BH,GAG7CG,I,49BCXF,MAAMQ,UAAiBC,EAAAA,cAA0B,mDASxCC,IACZC,KAAKV,MAAMW,WAAWF,EAAKG,OAVyB,8BAa/BC,IACrBH,KAAKV,MAAMc,eAAeD,MAb5BE,oBACEL,KAAKM,aAGS,yBACRN,KAAKV,MAAMiB,YAWnBC,WAAWT,GAAY,MACrB,MAAM,gBAAEU,EAAF,aAAmBC,GAAiBV,KAAKV,MACzCqB,EAAaZ,EAAKY,WAClBC,EAAW,kBAAiBb,EAAKG,KACjCW,GAAYC,EAAAA,EAAAA,IAAsB,CAAEH,WAAAA,EAAYF,gBAAAA,EAAiBC,aAAAA,IAEvE,OACE,2BACE,eAAIK,UAAU,8BAAd,UACE,cAAGC,KAAMJ,EAAT,UACE,gBAAKG,UAAU,uBAAuBE,IAAKlB,EAAKmB,UAAWC,IAAI,qBAGnE,eAAIJ,UAAU,UAAd,UACE,cAAGC,KAAMJ,EAAT,SAAmBb,EAAKqB,UAE1B,eAAIL,UAAU,UAAd,UACE,cAAGC,KAAMJ,EAAS,cAAY,UAAAb,EAAKsB,aAAL,eAAYC,QAAS,OAAIC,EAAY,mBAAnE,SACGxB,EAAKsB,WAGV,eAAIN,UAAU,UAAd,UACE,cAAGC,KAAMJ,EAAT,SAAmBb,EAAKyB,iBAE1B,eAAIT,UAAU,aAAd,UACE,SAAC,EAAAU,aAAD,CACE,aAAW,cACXC,KAAK,KACLC,UAAWd,EACXe,UAAW,IAAM5B,KAAKC,WAAWF,SAtB9BA,EAAKG,IA6BlB2B,kBACE,cACE,SAAC,IAAD,CACEC,MAAM,qCACNC,WAAW,YACXC,WAAW,gBACXC,YAAY,YACZC,OAAO,4FACPC,WAAW,GACXC,gBAAgB,GAChBC,aAAa,YAKnBC,iBACE,MAAM,MAAEC,EAAF,YAASC,EAAT,gBAAsB/B,EAAtB,aAAuCC,GAAiBV,KAAKV,MAC7DmD,EAAsBhC,GAAmBC,EAAagC,UAAYC,EAAAA,GAAAA,OAClEC,EAAgBH,EAAsB,YAAc,GACpDI,EAAcJ,EAAsB,IAAM,gBAEhD,OACE,iCACE,iBAAK1B,UAAU,kBAAf,WACE,gBAAKA,UAAU,wBAAf,UACE,SAAC,EAAA+B,YAAD,CAAaC,YAAY,eAAe5C,MAAOqC,EAAaQ,SAAUhD,KAAKiD,yBAG7E,SAAC,EAAAC,WAAD,CAAYnC,UAAW6B,EAAe5B,KAAM6B,EAA5C,0BAKF,gBAAK9B,UAAU,mBAAf,UACE,mBAAOA,UAAU,+CAAjB,WACE,4BACE,iCACE,mBADF,OAEE,kCAFF,OAGE,mCAHF,OAIE,sCACA,eAAIoC,MAAO,CAAEC,MAAO,cAGxB,2BAAQb,EAAMc,KAAKtD,GAASC,KAAKQ,WAAWT,eAOtDuD,aACE,MAAM,WAAEC,EAAF,WAAcC,GAAexD,KAAKV,MAExC,OAAKkE,EAIDD,EAAa,EACRvD,KAAKsC,iBAELtC,KAAK6B,kBANL,KAUX4B,SACE,MAAM,WAAED,EAAF,SAAcE,GAAa1D,KAAKV,MAEtC,OACE,SAAC,IAAD,CAAMoE,SAAUA,EAAhB,UACE,SAAC,aAAD,CAAeC,WAAYH,EAA3B,SAAwCxD,KAAKsD,kBAkBrD,MAAMtE,EAAqB,CACzBuB,UADyB,KAEzBN,WAFyB,KAGzBG,eAAcA,EAAAA,IAGhB,GAAetB,EAAAA,EAAAA,IAlBf,SAAyB8E,GACvB,MAAO,CACLF,UAAUG,EAAAA,EAAAA,GAAYD,EAAME,SAAU,SACtCvB,OAAOwB,EAAAA,EAAAA,IAASH,EAAMrB,OACtBC,aAAawB,EAAAA,EAAAA,IAAeJ,EAAMrB,OAClCgB,YAAYU,EAAAA,EAAAA,IAAcL,EAAMrB,OAChCiB,WAAYI,EAAMrB,MAAMiB,WACxB/C,gBAAiByD,EAAAA,GAAAA,gBACjBxD,aAAcyD,EAAAA,GAAAA,QAUiCnF,GAAqB4E,GAAUA,EAAMrB,OAAxF,CAA+F1C,I,4WCvKxF,SAASU,IACd,OAAO6D,MAAAA,IACL,MAAMC,QAAiBC,EAAAA,EAAAA,iBAAgBC,IAAI,oBAAqB,CAAEC,QAAS,IAAMC,KAAM,IACvFlF,GAASmF,EAAAA,EAAAA,IAAYL,EAAS9B,SAI3B,SAASoC,EAASzE,GACvB,OAAOkE,MAAAA,IACL,MAAMC,QAAiBC,EAAAA,EAAAA,iBAAgBC,IAAK,cAAarE,KACzDX,GAASqF,EAAAA,EAAAA,IAAWP,IACpB9E,GAASsF,EAAAA,EAAAA,KAAeC,EAAAA,EAAAA,GAAcT,MAInC,SAASU,IACd,OAAOX,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,KACvBsE,QAAiBC,EAAAA,EAAAA,iBAAgBC,IAAK,cAAaxE,EAAKG,cAC9DX,GAAS0F,EAAAA,EAAAA,IAAkBZ,KAIxB,SAASa,EAAchF,GAC5B,OAAOkE,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,WACvBuE,EAAAA,EAAAA,iBAAgBa,KAAM,cAAapF,EAAKG,aAAc,CAAEkF,OAAQlF,IACtEX,EAASwF,MAIN,SAASM,EAAiBnF,GAC/B,OAAOkE,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,WACvBuE,EAAAA,EAAAA,iBAAgBgB,OAAQ,cAAavF,EAAKG,cAAcA,KAC9DX,EAASwF,MAIN,SAASQ,EAAWnE,EAAcC,GACvC,OAAO+C,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,WACvBuE,EAAAA,EAAAA,iBAAgBkB,IAAK,cAAazF,EAAKG,KAAM,CAAEkB,KAAAA,EAAMC,MAAAA,IAC3D9B,EAASoF,EAAS5E,EAAKG,MAIpB,SAASuF,IACd,OAAOrB,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,KACvBsE,QAAiBC,EAAAA,EAAAA,iBAAgBC,IAAK,cAAaxE,EAAKG,aAC9DX,GAASmG,EAAAA,EAAAA,IAAiBrB,KAIvB,SAASsB,EAAaC,GAC3B,OAAOxB,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,WACvBuE,EAAAA,EAAAA,iBAAgBa,KAAM,cAAapF,EAAKG,YAAa,CAAE0F,QAASA,IACtErG,EAASkG,MAIN,SAASI,EAAgBD,GAC9B,OAAOxB,MAAO7E,EAAUyF,KACtB,MAAMjF,EAAOiF,IAAWjF,KAAKA,WACvBuE,EAAAA,EAAAA,iBAAgBgB,OAAQ,cAAavF,EAAKG,aAAa4F,mBAAmBF,MAChFrG,EAASkG,MAIN,SAASxF,EAAWC,GACzB,OAAOkE,MAAAA,UACCE,EAAAA,EAAAA,iBAAgBgB,OAAQ,cAAapF,KAC3CX,EAASgB,MAIN,SAASwF,EAAiBC,GAC/B,OAAO5B,MAAAA,UACCE,EAAAA,EAAAA,iBAAgBkB,IAAK,cAAaQ,EAAOC,kBAAkBD,EAAOZ,SAAU,CAChFzE,WAAYqF,EAAOrF,aAErBpB,EAASwF,Q,6JCtFN,SAASD,EAAc/E,GAC5B,MAAM2D,EAAW,CACfwC,IAAKnG,EAAKmB,UACVhB,GAAI,QAAUH,EAAKG,GACnBiG,SAAU,8BACVC,IAAK,GACLC,KAAMtG,EAAKqB,KACXkF,YAAa,CAAC,CAAExE,MAAO,QAASsE,IAAK,cACrCG,SAAU,CACR,CACEC,QAAQ,EACRC,KAAM,YACNvG,GAAK,gBAAeH,EAAKG,KACzBmG,KAAM,UACND,IAAM,kBAAiBrG,EAAKG,cAE9B,CACEsG,QAAQ,EACRC,KAAM,gBACNvG,GAAK,iBAAgBH,EAAKG,KAC1BmG,KAAM,WACND,IAAM,kBAAiBrG,EAAKG,iBAelC,OAVIgE,EAAAA,GAAAA,YAAAA,YACFR,EAAS6C,SAASG,KAAK,CACrBF,QAAQ,EACRC,KAAM,OACNvG,GAAK,kBAAiBH,EAAKG,KAC3BmG,KAAM,sBACND,IAAM,kBAAiBrG,EAAKG,iBAIzBwD,EAGF,SAASiD,EAAkBC,GAChC,MAAMC,EAAO/B,EAAc,CACzB5D,UAAW,8BACXhB,GAAI,EACJkB,KAAM,UACNC,MAAO,UACPG,YAAa,EACbb,WAAYmG,EAAAA,GAAAA,SAGd,IAAIC,EAGJ,IAAK,MAAMC,KAASH,EAAKN,SACvB,GAAIS,EAAM9G,GAAI+G,QAAQL,GAAY,EAAG,CACnCI,EAAMR,QAAS,EACfO,EAAOC,EACP,MAIJ,MAAO,CACLH,KAAMA,EACNE,KAAMA,K,4LC/DH,MAAM/C,EAAkBJ,GAAsBA,EAAMpB,YAC9C0E,EAAwBtD,GAAqBA,EAAMuD,kBACnDC,EAAiBxD,GAAqBA,EAAMyD,OAC5CpD,EAAiBL,GAAsBA,EAAMrB,MAAMjB,OAEnDgG,EAAU,CAAC1D,EAAkB2D,IACpC3D,EAAM7D,KAAKG,KAAOsH,SAASD,EAAe,IACrC3D,EAAM7D,KAGR,KAGIgE,EAAYH,IACvB,MAAM6D,EAAQC,OAAO9D,EAAMpB,YAAa,KAExC,OAAOoB,EAAMrB,MAAMoF,QAAQ5H,GAClB0H,EAAMG,KAAK7H,EAAKqB,SAIdyG,EAAkBjE,IAC7B,MAAM6D,EAAQC,OAAO9D,EAAMuD,kBAAmB,KAE9C,OAAOvD,EAAMkE,QAAQH,QAAQ3B,GACpByB,EAAMG,KAAK5B,EAAO+B,QAAUN,EAAMG,KAAK5B,EAAO3E,QAAUoG,EAAMG,KAAK5B,EAAO5E,SAUxE4G,EAA2B9D,IACtC,MAAM,QAAE4D,EAAF,aAAWpH,EAAX,gBAAyBD,GAAoByD,EAC7C+D,EAAgBH,EAAQI,MAAMC,GAAMA,EAAE/C,SAAW1E,EAAaR,KAC9DS,EAAasH,EAAgBA,EAActH,WAAamG,EAAAA,GAAAA,OAE9D,OAAOhG,EAAsB,CAAEH,WAAAA,EAAYD,aAAAA,EAAcD,gBAAAA,KAS9CK,EAAyBoD,IACpC,MAAM,WAAEvD,EAAF,aAAcD,EAAd,gBAA4BD,GAAoByD,EAChDkE,EAAU1H,EAAa2H,gBAAkB3H,EAAagC,UAAYC,EAAAA,GAAAA,MAClE2F,EAAkB3H,IAAemG,EAAAA,GAAAA,MAGvC,OAFgCsB,GAAWE,IAER7H","sources":["webpack://grafana/./public/app/core/components/connectWithCleanUp.tsx","webpack://grafana/./public/app/features/teams/TeamList.tsx","webpack://grafana/./public/app/features/teams/state/actions.ts","webpack://grafana/./public/app/features/teams/state/navModel.ts","webpack://grafana/./public/app/features/teams/state/selectors.ts"],"sourcesContent":["import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux';\nimport { cleanUpAction, StateSelector } from '../actions/cleanUp';\nimport React, { ComponentType, FunctionComponent, useEffect } from 'react';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\n\nexport const connectWithCleanUp = <\n  TStateProps extends {} = {},\n  TDispatchProps = {},\n  TOwnProps = {},\n  State = {},\n  TSelector extends object = {},\n  Statics = {}\n>(\n  mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,\n  mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,\n  stateSelector: StateSelector<TSelector>\n) => (Component: ComponentType<any>) => {\n  const ConnectedComponent = connect(\n    mapStateToProps,\n    mapDispatchToProps\n    // @ts-ignore\n  )(Component);\n\n  const ConnectedComponentWithCleanUp: FunctionComponent = (props) => {\n    const dispatch = useDispatch();\n    useEffect(() => {\n      return function cleanUp() {\n        dispatch(cleanUpAction({ stateSelector }));\n      };\n    }, [dispatch]);\n    // @ts-ignore\n    return <ConnectedComponent {...props} />;\n  };\n\n  ConnectedComponentWithCleanUp.displayName = `ConnectWithCleanUp(${ConnectedComponent.displayName})`;\n  hoistNonReactStatics(ConnectedComponentWithCleanUp, Component);\n  type Hoisted = typeof ConnectedComponentWithCleanUp & Statics;\n\n  return ConnectedComponentWithCleanUp as Hoisted;\n};\n","import React, { PureComponent } from 'react';\nimport Page from 'app/core/components/Page/Page';\nimport { DeleteButton, LinkButton, FilterInput } from '@grafana/ui';\nimport { NavModel } from '@grafana/data';\nimport EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';\nimport { OrgRole, StoreState, Team } from 'app/types';\nimport { deleteTeam, loadTeams } from './state/actions';\nimport { getSearchQuery, getTeams, getTeamsCount, isPermissionTeamAdmin } from './state/selectors';\nimport { getNavModel } from 'app/core/selectors/navModel';\nimport { config } from 'app/core/config';\nimport { contextSrv, User } from 'app/core/services/context_srv';\nimport { connectWithCleanUp } from '../../core/components/connectWithCleanUp';\nimport { setSearchQuery } from './state/reducers';\n\nexport interface Props {\n  navModel: NavModel;\n  teams: Team[];\n  searchQuery: string;\n  teamsCount: number;\n  hasFetched: boolean;\n  loadTeams: typeof loadTeams;\n  deleteTeam: typeof deleteTeam;\n  setSearchQuery: typeof setSearchQuery;\n  editorsCanAdmin: boolean;\n  signedInUser: User;\n}\n\nexport class TeamList extends PureComponent<Props, any> {\n  componentDidMount() {\n    this.fetchTeams();\n  }\n\n  async fetchTeams() {\n    await this.props.loadTeams();\n  }\n\n  deleteTeam = (team: Team) => {\n    this.props.deleteTeam(team.id);\n  };\n\n  onSearchQueryChange = (value: string) => {\n    this.props.setSearchQuery(value);\n  };\n\n  renderTeam(team: Team) {\n    const { editorsCanAdmin, signedInUser } = this.props;\n    const permission = team.permission;\n    const teamUrl = `org/teams/edit/${team.id}`;\n    const canDelete = isPermissionTeamAdmin({ permission, editorsCanAdmin, signedInUser });\n\n    return (\n      <tr key={team.id}>\n        <td className=\"width-4 text-center link-td\">\n          <a href={teamUrl}>\n            <img className=\"filter-table__avatar\" src={team.avatarUrl} alt=\"Team avatar\" />\n          </a>\n        </td>\n        <td className=\"link-td\">\n          <a href={teamUrl}>{team.name}</a>\n        </td>\n        <td className=\"link-td\">\n          <a href={teamUrl} aria-label={team.email?.length > 0 ? undefined : 'Empty email cell'}>\n            {team.email}\n          </a>\n        </td>\n        <td className=\"link-td\">\n          <a href={teamUrl}>{team.memberCount}</a>\n        </td>\n        <td className=\"text-right\">\n          <DeleteButton\n            aria-label=\"Delete team\"\n            size=\"sm\"\n            disabled={!canDelete}\n            onConfirm={() => this.deleteTeam(team)}\n          />\n        </td>\n      </tr>\n    );\n  }\n\n  renderEmptyList() {\n    return (\n      <EmptyListCTA\n        title=\"You haven't created any teams yet.\"\n        buttonIcon=\"users-alt\"\n        buttonLink=\"org/teams/new\"\n        buttonTitle=\" New team\"\n        proTip=\"Assign folder and dashboard permissions to teams instead of users to ease administration.\"\n        proTipLink=\"\"\n        proTipLinkTitle=\"\"\n        proTipTarget=\"_blank\"\n      />\n    );\n  }\n\n  renderTeamList() {\n    const { teams, searchQuery, editorsCanAdmin, signedInUser } = this.props;\n    const isCanAdminAndViewer = editorsCanAdmin && signedInUser.orgRole === OrgRole.Viewer;\n    const disabledClass = isCanAdminAndViewer ? ' disabled' : '';\n    const newTeamHref = isCanAdminAndViewer ? '#' : 'org/teams/new';\n\n    return (\n      <>\n        <div className=\"page-action-bar\">\n          <div className=\"gf-form gf-form--grow\">\n            <FilterInput placeholder=\"Search teams\" value={searchQuery} onChange={this.onSearchQueryChange} />\n          </div>\n\n          <LinkButton className={disabledClass} href={newTeamHref}>\n            New Team\n          </LinkButton>\n        </div>\n\n        <div className=\"admin-list-table\">\n          <table className=\"filter-table filter-table--hover form-inline\">\n            <thead>\n              <tr>\n                <th />\n                <th>Name</th>\n                <th>Email</th>\n                <th>Members</th>\n                <th style={{ width: '1%' }} />\n              </tr>\n            </thead>\n            <tbody>{teams.map((team) => this.renderTeam(team))}</tbody>\n          </table>\n        </div>\n      </>\n    );\n  }\n\n  renderList() {\n    const { teamsCount, hasFetched } = this.props;\n\n    if (!hasFetched) {\n      return null;\n    }\n\n    if (teamsCount > 0) {\n      return this.renderTeamList();\n    } else {\n      return this.renderEmptyList();\n    }\n  }\n\n  render() {\n    const { hasFetched, navModel } = this.props;\n\n    return (\n      <Page navModel={navModel}>\n        <Page.Contents isLoading={!hasFetched}>{this.renderList()}</Page.Contents>\n      </Page>\n    );\n  }\n}\n\nfunction mapStateToProps(state: StoreState) {\n  return {\n    navModel: getNavModel(state.navIndex, 'teams'),\n    teams: getTeams(state.teams),\n    searchQuery: getSearchQuery(state.teams),\n    teamsCount: getTeamsCount(state.teams),\n    hasFetched: state.teams.hasFetched,\n    editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests,\n    signedInUser: contextSrv.user, // this makes the feature toggle mockable/controllable from tests,\n  };\n}\n\nconst mapDispatchToProps = {\n  loadTeams,\n  deleteTeam,\n  setSearchQuery,\n};\n\nexport default connectWithCleanUp(mapStateToProps, mapDispatchToProps, (state) => state.teams)(TeamList);\n","import { getBackendSrv } from '@grafana/runtime';\n\nimport { TeamMember, ThunkResult } from 'app/types';\nimport { updateNavIndex } from 'app/core/actions';\nimport { buildNavModel } from './navModel';\nimport { teamGroupsLoaded, teamLoaded, teamMembersLoaded, teamsLoaded } from './reducers';\n\nexport function loadTeams(): ThunkResult<void> {\n  return async (dispatch) => {\n    const response = await getBackendSrv().get('/api/teams/search', { perpage: 1000, page: 1 });\n    dispatch(teamsLoaded(response.teams));\n  };\n}\n\nexport function loadTeam(id: number): ThunkResult<void> {\n  return async (dispatch) => {\n    const response = await getBackendSrv().get(`/api/teams/${id}`);\n    dispatch(teamLoaded(response));\n    dispatch(updateNavIndex(buildNavModel(response)));\n  };\n}\n\nexport function loadTeamMembers(): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    const response = await getBackendSrv().get(`/api/teams/${team.id}/members`);\n    dispatch(teamMembersLoaded(response));\n  };\n}\n\nexport function addTeamMember(id: number): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    await getBackendSrv().post(`/api/teams/${team.id}/members`, { userId: id });\n    dispatch(loadTeamMembers());\n  };\n}\n\nexport function removeTeamMember(id: number): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    await getBackendSrv().delete(`/api/teams/${team.id}/members/${id}`);\n    dispatch(loadTeamMembers());\n  };\n}\n\nexport function updateTeam(name: string, email: string): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    await getBackendSrv().put(`/api/teams/${team.id}`, { name, email });\n    dispatch(loadTeam(team.id));\n  };\n}\n\nexport function loadTeamGroups(): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    const response = await getBackendSrv().get(`/api/teams/${team.id}/groups`);\n    dispatch(teamGroupsLoaded(response));\n  };\n}\n\nexport function addTeamGroup(groupId: string): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    await getBackendSrv().post(`/api/teams/${team.id}/groups`, { groupId: groupId });\n    dispatch(loadTeamGroups());\n  };\n}\n\nexport function removeTeamGroup(groupId: string): ThunkResult<void> {\n  return async (dispatch, getStore) => {\n    const team = getStore().team.team;\n    await getBackendSrv().delete(`/api/teams/${team.id}/groups/${encodeURIComponent(groupId)}`);\n    dispatch(loadTeamGroups());\n  };\n}\n\nexport function deleteTeam(id: number): ThunkResult<void> {\n  return async (dispatch) => {\n    await getBackendSrv().delete(`/api/teams/${id}`);\n    dispatch(loadTeams());\n  };\n}\n\nexport function updateTeamMember(member: TeamMember): ThunkResult<void> {\n  return async (dispatch) => {\n    await getBackendSrv().put(`/api/teams/${member.teamId}/members/${member.userId}`, {\n      permission: member.permission,\n    });\n    dispatch(loadTeamMembers());\n  };\n}\n","import { Team, TeamPermissionLevel } from 'app/types';\nimport config from 'app/core/config';\nimport { NavModelItem, NavModel } from '@grafana/data';\n\nexport function buildNavModel(team: Team): NavModelItem {\n  const navModel = {\n    img: team.avatarUrl,\n    id: 'team-' + team.id,\n    subTitle: 'Manage members and settings',\n    url: '',\n    text: team.name,\n    breadcrumbs: [{ title: 'Teams', url: 'org/teams' }],\n    children: [\n      {\n        active: false,\n        icon: 'users-alt',\n        id: `team-members-${team.id}`,\n        text: 'Members',\n        url: `org/teams/edit/${team.id}/members`,\n      },\n      {\n        active: false,\n        icon: 'sliders-v-alt',\n        id: `team-settings-${team.id}`,\n        text: 'Settings',\n        url: `org/teams/edit/${team.id}/settings`,\n      },\n    ],\n  };\n\n  if (config.licenseInfo.hasLicense) {\n    navModel.children.push({\n      active: false,\n      icon: 'sync',\n      id: `team-groupsync-${team.id}`,\n      text: 'External group sync',\n      url: `org/teams/edit/${team.id}/groupsync`,\n    });\n  }\n\n  return navModel;\n}\n\nexport function getTeamLoadingNav(pageName: string): NavModel {\n  const main = buildNavModel({\n    avatarUrl: 'public/img/user_profile.png',\n    id: 1,\n    name: 'Loading',\n    email: 'loading',\n    memberCount: 0,\n    permission: TeamPermissionLevel.Member,\n  });\n\n  let node: NavModelItem;\n\n  // find active page\n  for (const child of main.children!) {\n    if (child.id!.indexOf(pageName) > 0) {\n      child.active = true;\n      node = child;\n      break;\n    }\n  }\n\n  return {\n    main: main,\n    node: node!,\n  };\n}\n","import { Team, TeamsState, TeamState, TeamMember, OrgRole, TeamPermissionLevel } from 'app/types';\nimport { User } from 'app/core/services/context_srv';\n\nexport const getSearchQuery = (state: TeamsState) => state.searchQuery;\nexport const getSearchMemberQuery = (state: TeamState) => state.searchMemberQuery;\nexport const getTeamGroups = (state: TeamState) => state.groups;\nexport const getTeamsCount = (state: TeamsState) => state.teams.length;\n\nexport const getTeam = (state: TeamState, currentTeamId: any): Team | null => {\n  if (state.team.id === parseInt(currentTeamId, 10)) {\n    return state.team;\n  }\n\n  return null;\n};\n\nexport const getTeams = (state: TeamsState) => {\n  const regex = RegExp(state.searchQuery, 'i');\n\n  return state.teams.filter((team) => {\n    return regex.test(team.name);\n  });\n};\n\nexport const getTeamMembers = (state: TeamState) => {\n  const regex = RegExp(state.searchMemberQuery, 'i');\n\n  return state.members.filter((member) => {\n    return regex.test(member.login) || regex.test(member.email) || regex.test(member.name);\n  });\n};\n\nexport interface Config {\n  members: TeamMember[];\n  editorsCanAdmin: boolean;\n  signedInUser: User;\n}\n\nexport const isSignedInUserTeamAdmin = (config: Config): boolean => {\n  const { members, signedInUser, editorsCanAdmin } = config;\n  const userInMembers = members.find((m) => m.userId === signedInUser.id);\n  const permission = userInMembers ? userInMembers.permission : TeamPermissionLevel.Member;\n\n  return isPermissionTeamAdmin({ permission, signedInUser, editorsCanAdmin });\n};\n\nexport interface PermissionConfig {\n  permission: TeamPermissionLevel;\n  editorsCanAdmin: boolean;\n  signedInUser: User;\n}\n\nexport const isPermissionTeamAdmin = (config: PermissionConfig): boolean => {\n  const { permission, signedInUser, editorsCanAdmin } = config;\n  const isAdmin = signedInUser.isGrafanaAdmin || signedInUser.orgRole === OrgRole.Admin;\n  const userIsTeamAdmin = permission === TeamPermissionLevel.Admin;\n  const isSignedInUserTeamAdmin = isAdmin || userIsTeamAdmin;\n\n  return isSignedInUserTeamAdmin || !editorsCanAdmin;\n};\n"],"names":["connectWithCleanUp","mapStateToProps","mapDispatchToProps","stateSelector","Component","ConnectedComponent","connect","ConnectedComponentWithCleanUp","props","dispatch","useDispatch","useEffect","cleanUpAction","displayName","hoistNonReactStatics","TeamList","PureComponent","team","this","deleteTeam","id","value","setSearchQuery","componentDidMount","fetchTeams","loadTeams","renderTeam","editorsCanAdmin","signedInUser","permission","teamUrl","canDelete","isPermissionTeamAdmin","className","href","src","avatarUrl","alt","name","email","length","undefined","memberCount","DeleteButton","size","disabled","onConfirm","renderEmptyList","title","buttonIcon","buttonLink","buttonTitle","proTip","proTipLink","proTipLinkTitle","proTipTarget","renderTeamList","teams","searchQuery","isCanAdminAndViewer","orgRole","OrgRole","disabledClass","newTeamHref","FilterInput","placeholder","onChange","onSearchQueryChange","LinkButton","style","width","map","renderList","teamsCount","hasFetched","render","navModel","isLoading","state","getNavModel","navIndex","getTeams","getSearchQuery","getTeamsCount","config","contextSrv","async","response","getBackendSrv","get","perpage","page","teamsLoaded","loadTeam","teamLoaded","updateNavIndex","buildNavModel","loadTeamMembers","getStore","teamMembersLoaded","addTeamMember","post","userId","removeTeamMember","delete","updateTeam","put","loadTeamGroups","teamGroupsLoaded","addTeamGroup","groupId","removeTeamGroup","encodeURIComponent","updateTeamMember","member","teamId","img","subTitle","url","text","breadcrumbs","children","active","icon","push","getTeamLoadingNav","pageName","main","TeamPermissionLevel","node","child","indexOf","getSearchMemberQuery","searchMemberQuery","getTeamGroups","groups","getTeam","currentTeamId","parseInt","regex","RegExp","filter","test","getTeamMembers","members","login","isSignedInUserTeamAdmin","userInMembers","find","m","isAdmin","isGrafanaAdmin","userIsTeamAdmin"],"sourceRoot":""}