github.com/aminovpavel/nomad@v0.11.8/ui/app/controllers/clients/index.js (about)

     1  import { alias, readOnly } from '@ember/object/computed';
     2  import { inject as service } from '@ember/service';
     3  import Controller, { inject as controller } from '@ember/controller';
     4  import { computed } from '@ember/object';
     5  import { scheduleOnce } from '@ember/runloop';
     6  import intersection from 'lodash.intersection';
     7  import SortableFactory from 'nomad-ui/mixins/sortable-factory';
     8  import Searchable from 'nomad-ui/mixins/searchable';
     9  import { serialize, deserializedQueryParam as selection } from 'nomad-ui/utils/qp-serialize';
    10  
    11  export default Controller.extend(
    12    SortableFactory(['id', 'name', 'compositeStatus', 'datacenter']),
    13    Searchable,
    14    {
    15      userSettings: service(),
    16      clientsController: controller('clients'),
    17  
    18      nodes: alias('model.nodes'),
    19      agents: alias('model.agents'),
    20  
    21      queryParams: {
    22        currentPage: 'page',
    23        searchTerm: 'search',
    24        sortProperty: 'sort',
    25        sortDescending: 'desc',
    26        qpClass: 'class',
    27        qpState: 'state',
    28        qpDatacenter: 'dc',
    29        qpVolume: 'volume',
    30      },
    31  
    32      currentPage: 1,
    33      pageSize: readOnly('userSettings.pageSize'),
    34  
    35      sortProperty: 'modifyIndex',
    36      sortDescending: true,
    37  
    38      searchProps: computed(() => ['id', 'name', 'datacenter']),
    39  
    40      qpClass: '',
    41      qpState: '',
    42      qpDatacenter: '',
    43      qpVolume: '',
    44  
    45      selectionClass: selection('qpClass'),
    46      selectionState: selection('qpState'),
    47      selectionDatacenter: selection('qpDatacenter'),
    48      selectionVolume: selection('qpVolume'),
    49  
    50      optionsClass: computed('nodes.[]', function() {
    51        const classes = Array.from(new Set(this.nodes.mapBy('nodeClass')))
    52          .compact()
    53          .without('');
    54  
    55        // Remove any invalid node classes from the query param/selection
    56        scheduleOnce('actions', () => {
    57          this.set('qpClass', serialize(intersection(classes, this.selectionClass)));
    58        });
    59  
    60        return classes.sort().map(dc => ({ key: dc, label: dc }));
    61      }),
    62  
    63      optionsState: computed(() => [
    64        { key: 'initializing', label: 'Initializing' },
    65        { key: 'ready', label: 'Ready' },
    66        { key: 'down', label: 'Down' },
    67        { key: 'ineligible', label: 'Ineligible' },
    68        { key: 'draining', label: 'Draining' },
    69      ]),
    70  
    71      optionsDatacenter: computed('nodes.[]', function() {
    72        const datacenters = Array.from(new Set(this.nodes.mapBy('datacenter'))).compact();
    73  
    74        // Remove any invalid datacenters from the query param/selection
    75        scheduleOnce('actions', () => {
    76          this.set('qpDatacenter', serialize(intersection(datacenters, this.selectionDatacenter)));
    77        });
    78  
    79        return datacenters.sort().map(dc => ({ key: dc, label: dc }));
    80      }),
    81  
    82      optionsVolume: computed('nodes.[]', function() {
    83        const flatten = (acc, val) => acc.concat(val.toArray());
    84  
    85        const allVolumes = this.nodes.mapBy('hostVolumes').reduce(flatten, []);
    86        const volumes = Array.from(new Set(allVolumes.mapBy('name')));
    87  
    88        scheduleOnce('actions', () => {
    89          this.set('qpVolume', serialize(intersection(volumes, this.selectionVolume)));
    90        });
    91  
    92        return volumes.sort().map(volume => ({ key: volume, label: volume }));
    93      }),
    94  
    95      filteredNodes: computed(
    96        'nodes.[]',
    97        'selectionClass',
    98        'selectionState',
    99        'selectionDatacenter',
   100        'selectionVolume',
   101        function() {
   102          const {
   103            selectionClass: classes,
   104            selectionState: states,
   105            selectionDatacenter: datacenters,
   106            selectionVolume: volumes,
   107          } = this;
   108  
   109          const onlyIneligible = states.includes('ineligible');
   110          const onlyDraining = states.includes('draining');
   111  
   112          // states is a composite of node status and other node states
   113          const statuses = states.without('ineligible').without('draining');
   114  
   115          return this.nodes.filter(node => {
   116            if (classes.length && !classes.includes(node.get('nodeClass'))) return false;
   117            if (statuses.length && !statuses.includes(node.get('status'))) return false;
   118            if (datacenters.length && !datacenters.includes(node.get('datacenter'))) return false;
   119            if (volumes.length && !node.hostVolumes.find(volume => volumes.includes(volume.name)))
   120              return false;
   121  
   122            if (onlyIneligible && node.get('isEligible')) return false;
   123            if (onlyDraining && !node.get('isDraining')) return false;
   124  
   125            return true;
   126          });
   127        }
   128      ),
   129  
   130      listToSort: alias('filteredNodes'),
   131      listToSearch: alias('listSorted'),
   132      sortedNodes: alias('listSearched'),
   133  
   134      isForbidden: alias('clientsController.isForbidden'),
   135  
   136      setFacetQueryParam(queryParam, selection) {
   137        this.set(queryParam, serialize(selection));
   138      },
   139  
   140      actions: {
   141        gotoNode(node) {
   142          this.transitionToRoute('clients.client', node);
   143        },
   144      },
   145    }
   146  );