| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- import angular from 'angular';
- import _ from 'lodash';
- export class MultiSelectDropdownCtrl {
- dropdownVisible: boolean;
- highlightIndex: number;
- linkText: string;
- options: Array<{ selected: boolean; text: string; value: string }>;
- selectedValues: Array<{ text: string; value: string }>;
- initialValues: string[];
- onUpdated: any;
- show() {
- this.highlightIndex = -1;
- this.options = this.options;
- this.selectedValues = this.options.filter(({ selected }) => selected);
- this.dropdownVisible = true;
- }
- hide() {
- this.dropdownVisible = false;
- }
- updateLinkText() {
- this.linkText =
- this.selectedValues.length === 1 ? this.selectedValues[0].text : `(${this.selectedValues.length}) selected`;
- }
- clearSelections() {
- this.selectedValues = _.filter(this.options, { selected: true });
- if (this.selectedValues.length > 1) {
- _.each(this.options, option => {
- option.selected = false;
- });
- } else {
- _.each(this.options, option => {
- option.selected = true;
- });
- }
- this.selectionsChanged();
- }
- selectValue(option: any) {
- if (!option) {
- return;
- }
- option.selected = !option.selected;
- this.selectionsChanged();
- }
- selectionsChanged() {
- this.selectedValues = _.filter(this.options, { selected: true });
- if (!this.selectedValues.length && this.options.length) {
- this.selectedValues = this.options.slice(0, 1);
- }
- this.updateLinkText();
- this.onUpdated({ values: this.selectedValues.map(({ value }) => value) });
- }
- onClickOutside() {
- this.selectedValues = _.filter(this.options, { selected: true });
- if (this.selectedValues.length === 0) {
- this.options[0].selected = true;
- this.selectionsChanged();
- }
- this.dropdownVisible = false;
- }
- init() {
- if (!this.options) {
- return;
- }
- this.options = this.options.map(o => ({
- ...o,
- selected: this.initialValues.includes(o.value),
- }));
- this.selectedValues = _.filter(this.options, { selected: true });
- if (!this.selectedValues.length) {
- this.options = this.options.map(o => ({
- ...o,
- selected: true,
- }));
- }
- this.updateLinkText();
- }
- updateSelection() {
- this.selectedValues = _.filter(this.options, { selected: true });
- if (!this.selectedValues.length && this.options.length) {
- this.options = this.options.map(o => ({
- ...o,
- selected: true,
- }));
- this.selectedValues = _.filter(this.options, { selected: true });
- this.selectionsChanged();
- }
- this.updateLinkText();
- }
- }
- /** @ngInject */
- export function multiSelectDropdown($window: any, $timeout: any) {
- return {
- scope: { onUpdated: '&', options: '=', initialValues: '=' },
- templateUrl: 'public/app/plugins/datasource/grafana-azure-monitor-datasource/partials/multi-select.directive.html',
- controller: MultiSelectDropdownCtrl,
- controllerAs: 'vm',
- bindToController: true,
- link: (scope: any, elem: any) => {
- const bodyEl = angular.element($window.document.body);
- const linkEl = elem.find('.variable-value-link');
- const inputEl = elem.find('input');
- function openDropdown() {
- inputEl.css('width', Math.max(linkEl.width(), 80) + 'px');
- inputEl.show();
- linkEl.hide();
- inputEl.focus();
- $timeout(
- () => {
- bodyEl.on('click', () => {
- bodyEl.on('click', bodyOnClick);
- });
- },
- 0,
- false
- );
- }
- function switchToLink() {
- inputEl.hide();
- linkEl.show();
- bodyEl.off('click', bodyOnClick);
- }
- function bodyOnClick(e: any) {
- if (elem.has(e.target).length === 0) {
- scope.$apply(() => {
- scope.vm.onClickOutside();
- });
- }
- }
- scope.$watch('vm.options', (newValue: any) => {
- if (newValue) {
- scope.vm.updateSelection(newValue);
- }
- });
- scope.$watch('vm.dropdownVisible', (newValue: any) => {
- if (newValue) {
- openDropdown();
- } else {
- switchToLink();
- }
- });
- scope.vm.init();
- },
- };
- }
- angular.module('grafana.directives').directive('multiSelect', multiSelectDropdown);
|