<commit_before>import execa from 'execa'
import puppeteer from 'puppeteer'

const percySnapshot = require('@percy/puppeteer')

const OTP_RR_TEST_CONFIG_PATH = '../percy/har-mock-config.yml'
const OTP_RR_TEST_JS_CONFIG_PATH = './percy/har-mock-config.js'

const MOCK_SERVER_PORT = 5000

// Puppeteer can take a long time to load, especially in some ci environments
jest.setTimeout(600000)

// How long to wait for each page to fully render before taking a screenshot
const PERCY_EXTRA_WAIT = 5000
const percySnapshotWithWait = async (page, name, enableJavaScript) => {
  await page.waitForTimeout(PERCY_EXTRA_WAIT)

  const namePrefix = process.env.PERCY_OTP_CONFIG_OVERRIDE || 'Mock OTP1 Server'
  await percySnapshot(page, `${namePrefix} - ${name}`, { enableJavaScript })
}

let browser
const serveAbortController = new AbortController()
const harAbortController = new AbortController()

/**
 * Loads a path
 */
async function loadPath(otpPath) {
  const page = await browser.newPage()
  const filePath = `http://localhost:${MOCK_SERVER_PORT}/#${otpPath}`
  await Promise.all([
    page.goto(filePath),
    page.waitForNavigation({ waitUntil: 'networkidle2' })
  ])

  return page
}

beforeAll(async () => {
  try {
    // Build OTP-RR main.js using new config file
    await execa('env', [
      `YAML_CONFIG=${
        process.env.PERCY_OTP_CONFIG_OVERRIDE || OTP_RR_TEST_CONFIG_PATH
      }`,
      `JS_CONFIG=${OTP_RR_TEST_JS_CONFIG_PATH}`,
      'yarn',
      'build'
    ])
    console.log('Built OTP-RR')

    // grab ATL har file to tmp
    if (process.env.HAR_URL) {
      await execa('curl', [process.env.HAR_URL, '-s', '--output', 'mock.har'])
      console.log('Downloaded HAR data')
    }
  } catch (error) {
    console.log(error)
  }
  console.log('Built OTP-RR and downloaded HAR data')

  try {
    execa('yarn', ['percy-serve', 'dist', '-p', MOCK_SERVER_PORT], {
      signal: serveAbortController.signal
    }).stdout.pipe(process.stdout)

    // Launch mock OTP server
    if (process.env.HAR_URL) {
      execa('yarn', ['percy-har-express', '-p', '9999', 'mock.har'], {
        signal: harAbortController.signal
      }).stdout.pipe(process.stdout)
    }

    // Web security is disabled to allow requests to the mock OTP server
    browser = await puppeteer.launch({
      args: ['--disable-web-security']
      // headless: false
    })

    // Fix time to Monday, March 14, 2022 14:22:22 GMT (10:22:22 AM EDT).
    browser.on('targetchanged', async (target) => {
      const targetPage = await target.page()
      const client = await targetPage.target().createCDPSession()
      await client.send('Runtime.evaluate', {
        expression:
          'Date.now = function() { return 1647267742000; }; Date.getTime = function() { return 1647267742000; }'
      })
    })
  } catch (error) {
    console.log(error)
  }

  // Give servers time to start up
  await execa('sleep', ['5'])
})

afterAll(async () => {
  try {
    serveAbortController.abort()
    harAbortController.abort()
    await browser.close()
  } catch (error) {
    console.log(error)
  }
  console.log('Closed mock server and headless browser')
})

// Puppeteer can take a long time to load, espeically in some ci environments
jest.setTimeout(600000)

/* These fixed routes allow us to test features that the static html screenshots
 * don't allow us to test. This is disabled, as percy doesn't support transitive.js
 * out of the box, even with javascript enabled.
 *
 * TODO: make transitive.js work with Percy, then complete this test suite
 */
// eslint-disable-next-line jest/no-commented-out-tests
/*
test('OTP-RR Fixed Routes', async () => {
  const transitive = await loadPath(
    '/?ui_activeSearch=5rzujqghc&ui_activeItinerary=0&fromPlace=Opus Music Store%2C Decatur%2C GA%3A%3A33.77505%2C-84.300178&toPlace=Five Points Station (MARTA Stop ID 908981)%3A%3A33.753837%2C-84.391397&date=2022-03-09&time=09%3A58&arriveBy=false&mode=WALK%2CBUS%2CSUBWAY%2CTRAM%2CFLEX_EGRESS%2CFLEX_ACCESS%2CFLEX_DIRECT&showIntermediateStops=true&maxWalkDistance=1207&optimize=QUICK&walkSpeed=1.34&ignoreRealtimeUpdates=true&wheelchair=false&numItineraries=3&otherThanPreferredRoutesPenalty=900'
  )
  await percySnapshotWithWait(transitive, 'Itinerary (with transitive)', true)

  const routes = await loadPath('/route')
  await percySnapshotWithWait(routes, 'Route Viewer (with transitive)', true)
})
*/

// Percy screenshot is not an assertion, but that's ok
// eslint-disable-next-line jest/expect-expect
test('OTP-RR', async () => {
  const page = await loadPath('/')
  await page.setViewport({
    height: 1080,
    width: 1920
  })

  await percySnapshotWithWait(page, 'Main Page (without styling)')

  // Plan a trip
  await page.goto(
    `http://localhost:${MOCK_SERVER_PORT}/#/?ui_activeSearch=5rzujqghc&ui_activeItinerary=0&fromPlace=Opus Music Store%2C Decatur%2C GA%3A%3A33.77505%2C-84.300178&toPlace=Five Points Station (MARTA Stop ID 908981)%3A%3A33.753837%2C-84.391397&date=2022-05-09&time=09%3A58&arriveBy=false&mode=WALK%2CBUS%2CSUBWAY%2CTRAM%2CFLEX_EGRESS%2CFLEX_ACCESS%2CFLEX_DIRECT&showIntermediateStops=true&maxWalkDistance=1207&optimize=QUICK&walkSpeed=1.34&ignoreRealtimeUpdates=true&wheelchair=false&numItineraries=3&otherThanPreferredRoutesPenalty=900`
  )
  await page.waitForNavigation({ waitUntil: 'networkidle2' })
  await page.waitForSelector('.title')

  await percySnapshotWithWait(page, 'Batch Itinerary')

  // Select a trip
  await page.waitForSelector('.title:nth-of-type(1)')
  await page.click('.title:nth-of-type(1)')

  await percySnapshotWithWait(page, 'Batch Itinerary Selected')

  // Open Trip Viewer
  await page.waitForTimeout(2000)
  const [tripViewerButton] = await page.$x(
    "//button[contains(., 'Trip Viewer')]"
  )
  await tripViewerButton.click()
  await page.waitForSelector('div.trip-viewer-body')
  await page.waitForTimeout(1000)
  await percySnapshotWithWait(page, 'Trip Viewer')

  // Open stop viewer from trip viewer
  await page.click(
    'div.trip-viewer-body > div:nth-child(3) > div.stop-button-container > button'
  )
  await page.waitForSelector('.stop-viewer')

  await percySnapshotWithWait(page, 'Stop Viewer')

  // Open schedule view
  await page.waitForSelector('button.link-button.pull-right')
  await page.click('button.link-button.pull-right')
  await page.waitForTimeout(3000) // Slow animation
  await percySnapshotWithWait(page, 'Schedule Viewer')
  // TODO: is the schedule date wrong?

  // Open route viewer
  const [routeViewerButton] = await page.$x(
    "//button[contains(., 'View Routes')]"
  )
  await routeViewerButton.click()
  await page.waitForSelector('.route-viewer')
  await page.waitForTimeout(5000)

  await percySnapshotWithWait(page, 'Route Viewer')

  // Open Specific Route`
  const [busRouteButton] = await page.$x(
    "//span[contains(., 'Sugarloaf Mills - Lindbergh Center')]"
  )
  await busRouteButton.click()
  await page.waitForSelector('#headsign-selector')

  await percySnapshotWithWait(page, 'Route Viewer Showing Route 410')

  // View multiple patterns
  // Click second option
  const secondPatternOption = await page.$$eval(
    'option',
    (options) => options.find((o) => o.innerText.includes('Sugarloaf'))?.value
  )
  await page.select('select#headsign-selector', secondPatternOption)

  await page.waitForSelector('#headsign-selector-label')
  await page.waitForTimeout(1000)

  // Click first option
  const firstPatternOption = await page.$$eval(
    'option',
    (options) => options.find((o) => o.innerText.includes('Lindbergh'))?.value
  )
  await page.select('select#headsign-selector', firstPatternOption)
  await page.waitForTimeout(1000)

  await percySnapshotWithWait(page, 'Pattern Viewer Showing Route 410')

  // Stop viewer from pattern viewer
  const [patternStopButton] = await page.$x(
    "//a[contains(., 'Sugarloaf Mills GCT Park and Ride')]"
  )
  await patternStopButton.click()
  await page.waitForSelector('.stop-viewer')

  // Activate all layers
  await page.$$eval('.leaflet-control-layers-selector', (checks) =>
    checks.forEach((c) => c.click())
  )
  await page.waitForTimeout(1000)

  // Go back to trip planner
  const [tripPlannerButton] = await page.$x(
    "//button[contains(., 'Plan Trip')]"
  )
  await tripPlannerButton.click()
  await page.waitForSelector('.batch-routing-panel')
  await page.waitForTimeout(3000)
  const [viewAllOptionsButton] = await page.$x(
    "//button[contains(., 'View all options')]"
  )
  await viewAllOptionsButton.click()
  await page.waitForTimeout(1000)

  // Need to explicitly select the first itinerary to reset map position
  await page.goto(`${page.url()}&ui_activeItinerary=1`)
  await page.waitForTimeout(2000)

  await percySnapshotWithWait(page, 'Batch Itinerary Showing Bikes')
})
<commit_msg>ci: update percy date<commit_after>import execa from 'execa'
import puppeteer from 'puppeteer'

const percySnapshot = require('@percy/puppeteer')

const OTP_RR_TEST_CONFIG_PATH = '../percy/har-mock-config.yml'
const OTP_RR_TEST_JS_CONFIG_PATH = './percy/har-mock-config.js'

const MOCK_SERVER_PORT = 5000

// Puppeteer can take a long time to load, especially in some ci environments
jest.setTimeout(600000)

// How long to wait for each page to fully render before taking a screenshot
const PERCY_EXTRA_WAIT = 5000
const percySnapshotWithWait = async (page, name, enableJavaScript) => {
  await page.waitForTimeout(PERCY_EXTRA_WAIT)

  const namePrefix = process.env.PERCY_OTP_CONFIG_OVERRIDE || 'Mock OTP1 Server'
  await percySnapshot(page, `${namePrefix} - ${name}`, { enableJavaScript })
}

let browser
const serveAbortController = new AbortController()
const harAbortController = new AbortController()

/**
 * Loads a path
 */
async function loadPath(otpPath) {
  const page = await browser.newPage()
  const filePath = `http://localhost:${MOCK_SERVER_PORT}/#${otpPath}`
  await Promise.all([
    page.goto(filePath),
    page.waitForNavigation({ waitUntil: 'networkidle2' })
  ])

  return page
}

beforeAll(async () => {
  try {
    // Build OTP-RR main.js using new config file
    await execa('env', [
      `YAML_CONFIG=${
        process.env.PERCY_OTP_CONFIG_OVERRIDE || OTP_RR_TEST_CONFIG_PATH
      }`,
      `JS_CONFIG=${OTP_RR_TEST_JS_CONFIG_PATH}`,
      'yarn',
      'build'
    ])
    console.log('Built OTP-RR')

    // grab ATL har file to tmp
    if (process.env.HAR_URL) {
      await execa('curl', [process.env.HAR_URL, '-s', '--output', 'mock.har'])
      console.log('Downloaded HAR data')
    }
  } catch (error) {
    console.log(error)
  }
  console.log('Built OTP-RR and downloaded HAR data')

  try {
    execa('yarn', ['percy-serve', 'dist', '-p', MOCK_SERVER_PORT], {
      signal: serveAbortController.signal
    }).stdout.pipe(process.stdout)

    // Launch mock OTP server
    if (process.env.HAR_URL) {
      execa('yarn', ['percy-har-express', '-p', '9999', 'mock.har'], {
        signal: harAbortController.signal
      }).stdout.pipe(process.stdout)
    }

    // Web security is disabled to allow requests to the mock OTP server
    browser = await puppeteer.launch({
      args: ['--disable-web-security']
      // headless: false
    })

    // Fix time to Monday, March 14, 2022 14:22:22 GMT (10:22:22 AM EDT).
    browser.on('targetchanged', async (target) => {
      const targetPage = await target.page()
      const client = await targetPage.target().createCDPSession()
      await client.send('Runtime.evaluate', {
        expression:
          'Date.now = function() { return 1647267742000; }; Date.getTime = function() { return 1647267742000; }'
      })
    })
  } catch (error) {
    console.log(error)
  }

  // Give servers time to start up
  await execa('sleep', ['5'])
})

afterAll(async () => {
  try {
    serveAbortController.abort()
    harAbortController.abort()
    await browser.close()
  } catch (error) {
    console.log(error)
  }
  console.log('Closed mock server and headless browser')
})

// Puppeteer can take a long time to load, espeically in some ci environments
jest.setTimeout(600000)

/* These fixed routes allow us to test features that the static html screenshots
 * don't allow us to test. This is disabled, as percy doesn't support transitive.js
 * out of the box, even with javascript enabled.
 *
 * TODO: make transitive.js work with Percy, then complete this test suite
 */
// eslint-disable-next-line jest/no-commented-out-tests
/*
test('OTP-RR Fixed Routes', async () => {
  const transitive = await loadPath(
    '/?ui_activeSearch=5rzujqghc&ui_activeItinerary=0&fromPlace=Opus Music Store%2C Decatur%2C GA%3A%3A33.77505%2C-84.300178&toPlace=Five Points Station (MARTA Stop ID 908981)%3A%3A33.753837%2C-84.391397&date=2022-03-09&time=09%3A58&arriveBy=false&mode=WALK%2CBUS%2CSUBWAY%2CTRAM%2CFLEX_EGRESS%2CFLEX_ACCESS%2CFLEX_DIRECT&showIntermediateStops=true&maxWalkDistance=1207&optimize=QUICK&walkSpeed=1.34&ignoreRealtimeUpdates=true&wheelchair=false&numItineraries=3&otherThanPreferredRoutesPenalty=900'
  )
  await percySnapshotWithWait(transitive, 'Itinerary (with transitive)', true)

  const routes = await loadPath('/route')
  await percySnapshotWithWait(routes, 'Route Viewer (with transitive)', true)
})
*/

// Percy screenshot is not an assertion, but that's ok
// eslint-disable-next-line jest/expect-expect
test('OTP-RR', async () => {
  const page = await loadPath('/')
  await page.setViewport({
    height: 1080,
    width: 1920
  })

  await percySnapshotWithWait(page, 'Main Page (without styling)')

  // Plan a trip
  await page.goto(
    `http://localhost:${MOCK_SERVER_PORT}/#/?ui_activeSearch=5rzujqghc&ui_activeItinerary=0&fromPlace=Opus Music Store%2C Decatur%2C GA%3A%3A33.77505%2C-84.300178&toPlace=Five Points Station (MARTA Stop ID 908981)%3A%3A33.753837%2C-84.391397&date=2022-10-10&time=09%3A58&arriveBy=false&mode=WALK%2CBUS%2CSUBWAY%2CTRAM%2CFLEX_EGRESS%2CFLEX_ACCESS%2CFLEX_DIRECT&showIntermediateStops=true&maxWalkDistance=1207&optimize=QUICK&walkSpeed=1.34&ignoreRealtimeUpdates=true&wheelchair=false&numItineraries=3&otherThanPreferredRoutesPenalty=900`
  )
  await page.waitForNavigation({ waitUntil: 'networkidle2' })
  await page.waitForSelector('.title')

  await percySnapshotWithWait(page, 'Batch Itinerary')

  // Select a trip
  await page.waitForSelector('.title:nth-of-type(1)')
  await page.click('.title:nth-of-type(1)')

  await percySnapshotWithWait(page, 'Batch Itinerary Selected')

  // Open Trip Viewer
  await page.waitForTimeout(2000)
  const [tripViewerButton] = await page.$x(
    "//button[contains(., 'Trip Viewer')]"
  )
  await tripViewerButton.click()
  await page.waitForSelector('div.trip-viewer-body')
  await page.waitForTimeout(1000)
  await percySnapshotWithWait(page, 'Trip Viewer')

  // Open stop viewer from trip viewer
  await page.click(
    'div.trip-viewer-body > div:nth-child(3) > div.stop-button-container > button'
  )
  await page.waitForSelector('.stop-viewer')

  await percySnapshotWithWait(page, 'Stop Viewer')

  // Open schedule view
  await page.waitForSelector('button.link-button.pull-right')
  await page.click('button.link-button.pull-right')
  await page.waitForTimeout(3000) // Slow animation
  await percySnapshotWithWait(page, 'Schedule Viewer')
  // TODO: is the schedule date wrong?

  // Open route viewer
  const [routeViewerButton] = await page.$x(
    "//button[contains(., 'View Routes')]"
  )
  await routeViewerButton.click()
  await page.waitForSelector('.route-viewer')
  await page.waitForTimeout(5000)

  await percySnapshotWithWait(page, 'Route Viewer')

  // Open Specific Route`
  const [busRouteButton] = await page.$x(
    "//span[contains(., 'Sugarloaf Mills - Lindbergh Center')]"
  )
  await busRouteButton.click()
  await page.waitForSelector('#headsign-selector')

  await percySnapshotWithWait(page, 'Route Viewer Showing Route 410')

  // View multiple patterns
  // Click second option
  const secondPatternOption = await page.$$eval(
    'option',
    (options) => options.find((o) => o.innerText.includes('Sugarloaf'))?.value
  )
  await page.select('select#headsign-selector', secondPatternOption)

  await page.waitForSelector('#headsign-selector-label')
  await page.waitForTimeout(1000)

  // Click first option
  const firstPatternOption = await page.$$eval(
    'option',
    (options) => options.find((o) => o.innerText.includes('Lindbergh'))?.value
  )
  await page.select('select#headsign-selector', firstPatternOption)
  await page.waitForTimeout(1000)

  await percySnapshotWithWait(page, 'Pattern Viewer Showing Route 410')

  // Stop viewer from pattern viewer
  const [patternStopButton] = await page.$x(
    "//a[contains(., 'Sugarloaf Mills GCT Park and Ride')]"
  )
  await patternStopButton.click()
  await page.waitForSelector('.stop-viewer')

  // Activate all layers
  await page.$$eval('.leaflet-control-layers-selector', (checks) =>
    checks.forEach((c) => c.click())
  )
  await page.waitForTimeout(1000)

  // Go back to trip planner
  const [tripPlannerButton] = await page.$x(
    "//button[contains(., 'Plan Trip')]"
  )
  await tripPlannerButton.click()
  await page.waitForSelector('.batch-routing-panel')
  await page.waitForTimeout(3000)
  const [viewAllOptionsButton] = await page.$x(
    "//button[contains(., 'View all options')]"
  )
  await viewAllOptionsButton.click()
  await page.waitForTimeout(1000)

  // Need to explicitly select the first itinerary to reset map position
  await page.goto(`${page.url()}&ui_activeItinerary=1`)
  await page.waitForTimeout(2000)

  await percySnapshotWithWait(page, 'Batch Itinerary Showing Bikes')
})
<|endoftext|>


<commit_before>define('vis',
    [
        'kbaseBarchart',
        'kbaseHeatmap',
        'kbaseLinechart',
        'kbaseLineSerieschart',
        'kbaseScatterplot',
        'kbasePiechart',
        'kbaseForcedNetwork',
        'kbaseTreechart',
        'kbaseCircularHeatmap',
    ],
    function() {

    }
);

<commit_msg>added the chord chart<commit_after>define('vis',
    [
        'kbaseBarchart',
        'kbaseHeatmap',
        'kbaseLinechart',
        'kbaseLineSerieschart',
        'kbaseScatterplot',
        'kbasePiechart',
        'kbaseForcedNetwork',
        'kbaseTreechart',
        'kbaseCircularHeatmap',
        'kbaseChordchart',
    ],
    function() {

    }
);

<|endoftext|>


<commit_before>const os = require('os');
const fs = require('fs');
const run = require('./run.js');
const platform = require('./platform.js');

exports.getStatus = getStatus;
exports.getConnectedNetwork = getConnectedNetwork;
exports.scan = scan;
exports.startAP = startAP;
exports.stopAP = stopAP;
exports.defineNetwork = defineNetwork;
exports.removeNetwork = removeNetwork;
exports.getKnownNetworks = getKnownNetworks;
exports.broadcastBeacon = broadcastBeacon;
exports.checkConnection = checkConnection;
exports.waitForWiFi = waitForWiFi;

// The Edison device can't scan for wifi networks while in AP mode, so
// we've got to scan before we enter AP mode and save the results. They're a
// global variable because this code needs to ship
exports.preliminaryScanResults = [];

/**
 * Determine whether we have a wifi connection with the `wpa_cli
 * status` command. This function returns a Promise that resolves to a
 * string.  On my Rasberry Pi, the string is "DISCONNECTED" or
 * "INACTIVE" when there is no connection and is "COMPLETED" when
 * there is a connection. There are other possible string values when
 * a connection is being established
 */
function getStatus() {
  return run(platform.getStatus);
}

/**
 * Determine the ssid of the wifi network we are connected to.
 * This function returns a Promise that resolves to a string.
 * The string will be empty if not connected.
 */
function getConnectedNetwork() {
  return run(platform.getConnectedNetwork);
}

/**
 * Scan for available wifi networks using `iwlist wlan0 scan`.
 * Returns a Promise that resolves to an array of strings. Each string
 * is the ssid of a wifi network. They are sorted by signal strength from
 * strongest to weakest. On a Raspberry Pi, a scan seems to require root
 * privileges.
 *
 * On a Raspberry Pi 3, this function works when the device is in AP mode.
 * The Intel Edison, however, cannot scan while in AP mode: iwlist fails
 * with an error. iwlist sometimes also fails with an error when the
 * hardware is busy, so this function will try multiple times if you
 * pass a number. If all attempts fail, the promise is resolved to
 * an empty array.
 */
function scan(numAttempts) {
  numAttempts = numAttempts || 1;
  return new Promise(function(resolve) {
    let attempts = 0;

    function tryScan() {
      attempts++;

      _scan()
        .then((out) => {
          resolve(out.length ? out.split('\n') : []);
        })
        .catch((err) => {
          console.error('Scan attempt', attempts, 'failed:',
                        err.message || err);

          if (attempts >= numAttempts) {
            console.error('Giving up. No scan results available.');
            resolve([]);
          } else {
            console.error('Will try again in 3 seconds.');
            setTimeout(tryScan, 3000);
          }
        });
    }

    tryScan();
  });

  function _scan() {
    return run(platform.scan);
  }
}

/**
 * Enable an access point that users can connect to to configure the device.
 *
 * This command runs different commands on Raspbery Pi Rasbian and Edison Yocto.
 *
 * It requires that hostapd and udhcpd are installed on the system but not
 * enabled, so that they do not automatically run when the device boots up.
 * It also requires that hostapd and udhcpd have appropriate config files
 * that define the ssid for the wifi network to be created, for example.
 * Also, the udhcpd config file should be set up to work with the IP address
 * of the device.
 *
 * XXX
 * It would probably be better if the IP address, SSID and password were
 * options to this function rather than being hardcoded in system config
 * files. (Each device ought to be able to add a random number to its
 * SSID, for example, so that when you've got multiple devices they don't
 * all try to create the same network).
 *
 * This function returns a Promise that resolves when the necessary
 * commands have been run.  This does not necessarily mean that the AP
 * will be functional, however. The setup process might take a few
 * seconds to complete before the user will be able to see and connect
 * to the network.
 */
function startAP(ip) {
  return run(platform.startAP, {IP: ip});
}

/**
 * Like startAP(), but take the access point down, using platform-dependent
 * commands.
 *
 * Returns a promise that resolves when the commands have been run. At
 * this point, the AP should be in the process of stopping but may not
 * yet be completely down.
 */
function stopAP() {
  return run(platform.stopAP);
}

/**
 * This function uses wpa_cli to add the specified network ssid and password
 * to the wpa_supplicant.conf file. This assumes that wpa_supplicant is
 * configured to run automatically at boot time and is configured to work
 * with wpa_cli.
 *
 * If the system is not connected to a wifi network, calling this
 * command with a valid ssid and password should cause it to connect.
 */
function defineNetwork(ssid, password) {
  return run(password ? platform.defineNetwork : platform.defineOpenNetwork, {
    SSID: ssid,
    PSK: password,
  });
}

/**
 * This function uses wpa_cli to remove the network with the given ID.
 */
function removeNetwork(id) {
  return run(platform.removeNetwork, {ID: id});
}

/**
 * Return a Promise that resolves to an array of known wifi network names
 */
function getKnownNetworks() {
  return run(platform.getKnownNetworks)
    .then((out) => out.length ? out.split('\n') : []);
}

/**
 * Broadcast a Bluetooth Eddystone beacon with the local IP address.
 */
function broadcastBeacon() {
  let cmd = platform.broadcastBeacon;

  let ip = null;
  const ifaces = os.networkInterfaces();

  // Check out wlan0 first.
  if (ifaces.hasOwnProperty('wlan0')) {
    for (const addr of ifaces.wlan0) {
      if (addr.family !== 'IPv4' || addr.internal) {
        continue;
      }

      ip = addr.address;
      break;
    }
  }

  // If we didn't get an IP address, check out eth0.
  if (ip === null && ifaces.hasOwnProperty('eth0')) {
    for (const addr of ifaces.eth0) {
      if (addr.family !== 'IPv4' || addr.internal) {
        continue;
      }

      ip = addr.address;
      break;
    }
  }

  // If we still don't have an IP, bail.
  if (ip === null) {
    // Don't reject, as this isn't really critical.
    return Promise.resolve();
  }

  // OGF + OCF
  cmd += ' 0x08 0x0008';

  // Length byte
  const length1 = 14 + ip.length;
  cmd += ` ${length1.toString(16)}`;

  // Flags
  cmd += ' 02 01 06';

  // UUIDs
  cmd += ' 03 03 aa fe';

  // Length byte
  const length2 = 6 + ip.length;
  cmd += ` ${length2.toString(16)}`;

  // Service data type value
  cmd += ' 16';

  // UUIDs
  cmd += ' aa fe';

  // Frame type
  cmd += ' 10';

  // TX power
  cmd += ' 00';

  // URL scheme
  cmd += ' 02';

  // URL
  cmd += ` ${ip.split('').map((x) => x.charCodeAt(0).toString(16)).join(' ')}`;

  // Trailer
  cmd += ' 00 00 00 00 00 00 00 00';

  return run(cmd);
}

function checkConnection() {
  if (fs.existsSync('wifiskip')) {
    return Promise.resolve(true);
  }
  return getStatus().then(() => {
    // Wait until we have a working wifi connection. Retry every 3 seconds up
    // to 10 times. If we are connected, then start the Gateway client.
    // If we never get a wifi connection, go into AP mode.
    // Before we start, though, let the user know that something is happening
    waitForWiFi(20, 3000).then(() => {
      return true;
    }).catch((err) => {
      console.log('No wifi connection found. Starting the AP...', err);
      // Scan for wifi networks now because we can't always scan once
      // the AP is being broadcast, retrying up to 10 times
      scan(10).then((ssids) => {
        exports.preliminaryScanResults = ssids; // Remember ssids
        console.log('No wifi found; entering AP mode');
        startAP(platform.ap_ip);
      });

      return false;
    });
  }).catch((err) => {
    console.error('Error checking wifi adapter presence', err);
    return true;
  });
}

// Return a promise, then check every interval ms for a wifi connection.
// Resolve the promise when we're connected. Or, if we aren't connected
// after maxAttempts attempts, then reject the promise
function waitForWiFi(maxAttempts, interval) {
  return new Promise(function(resolve, reject) {
    let attempts = 0;

    // first of all we query wpa_supplicant if there's a wifi AP configured
    run(platform.listNetworks)
      .then((out) => {
        console.log('List Networks command executed:', out);
        if (out.includes('\n0\t')) {
          // there's at least one wifi AP configured. Let's wait to see if it
          // will connect
          check();
        } else {
          // No wifi AP configured. Let's skip the wait and start the setup
          // immediately
          reject();
        }
      })
      .catch((err) => console.error('Error listing Networks:', err));

    function check() {
      attempts++;
      console.log('check', attempts);
      getStatus()
        .then((status) => {
          console.log(status);
          if (status === 'COMPLETED') {
            console.log('WiFi connection found. resolving');
            checkForAddress();
            console.log('resolved');
          } else {
            console.log('No wifi connection on attempt', attempts);
            retryOrGiveUp();
          }
        })
        .catch((err) => {
          console.error('Error checking wifi on attempt', attempts, ':', err);
          retryOrGiveUp();
        });
    }

    function checkForAddress() {
      const ifaces = os.networkInterfaces();

      if (ifaces.hasOwnProperty('wlan0')) {
        for (const addr of ifaces.wlan0) {
          if (addr.family !== 'IPv4' || addr.internal) {
            continue;
          }

          resolve();
          return;
        }
      }

      retryOrGiveUp();
    }

    function retryOrGiveUp() {
      if (attempts >= maxAttempts) {
        console.error('Giving up. No wifi available.');
        reject();
      } else {
        setTimeout(check, interval);
      }
    }
  });
}
<commit_msg>Fix missing return on a promise<commit_after>const os = require('os');
const fs = require('fs');
const run = require('./run.js');
const platform = require('./platform.js');

exports.getStatus = getStatus;
exports.getConnectedNetwork = getConnectedNetwork;
exports.scan = scan;
exports.startAP = startAP;
exports.stopAP = stopAP;
exports.defineNetwork = defineNetwork;
exports.removeNetwork = removeNetwork;
exports.getKnownNetworks = getKnownNetworks;
exports.broadcastBeacon = broadcastBeacon;
exports.checkConnection = checkConnection;
exports.waitForWiFi = waitForWiFi;

// The Edison device can't scan for wifi networks while in AP mode, so
// we've got to scan before we enter AP mode and save the results. They're a
// global variable because this code needs to ship
exports.preliminaryScanResults = [];

/**
 * Determine whether we have a wifi connection with the `wpa_cli
 * status` command. This function returns a Promise that resolves to a
 * string.  On my Rasberry Pi, the string is "DISCONNECTED" or
 * "INACTIVE" when there is no connection and is "COMPLETED" when
 * there is a connection. There are other possible string values when
 * a connection is being established
 */
function getStatus() {
  return run(platform.getStatus);
}

/**
 * Determine the ssid of the wifi network we are connected to.
 * This function returns a Promise that resolves to a string.
 * The string will be empty if not connected.
 */
function getConnectedNetwork() {
  return run(platform.getConnectedNetwork);
}

/**
 * Scan for available wifi networks using `iwlist wlan0 scan`.
 * Returns a Promise that resolves to an array of strings. Each string
 * is the ssid of a wifi network. They are sorted by signal strength from
 * strongest to weakest. On a Raspberry Pi, a scan seems to require root
 * privileges.
 *
 * On a Raspberry Pi 3, this function works when the device is in AP mode.
 * The Intel Edison, however, cannot scan while in AP mode: iwlist fails
 * with an error. iwlist sometimes also fails with an error when the
 * hardware is busy, so this function will try multiple times if you
 * pass a number. If all attempts fail, the promise is resolved to
 * an empty array.
 */
function scan(numAttempts) {
  numAttempts = numAttempts || 1;
  return new Promise(function(resolve) {
    let attempts = 0;

    function tryScan() {
      attempts++;

      _scan()
        .then((out) => {
          resolve(out.length ? out.split('\n') : []);
        })
        .catch((err) => {
          console.error('Scan attempt', attempts, 'failed:',
                        err.message || err);

          if (attempts >= numAttempts) {
            console.error('Giving up. No scan results available.');
            resolve([]);
          } else {
            console.error('Will try again in 3 seconds.');
            setTimeout(tryScan, 3000);
          }
        });
    }

    tryScan();
  });

  function _scan() {
    return run(platform.scan);
  }
}

/**
 * Enable an access point that users can connect to to configure the device.
 *
 * This command runs different commands on Raspbery Pi Rasbian and Edison Yocto.
 *
 * It requires that hostapd and udhcpd are installed on the system but not
 * enabled, so that they do not automatically run when the device boots up.
 * It also requires that hostapd and udhcpd have appropriate config files
 * that define the ssid for the wifi network to be created, for example.
 * Also, the udhcpd config file should be set up to work with the IP address
 * of the device.
 *
 * XXX
 * It would probably be better if the IP address, SSID and password were
 * options to this function rather than being hardcoded in system config
 * files. (Each device ought to be able to add a random number to its
 * SSID, for example, so that when you've got multiple devices they don't
 * all try to create the same network).
 *
 * This function returns a Promise that resolves when the necessary
 * commands have been run.  This does not necessarily mean that the AP
 * will be functional, however. The setup process might take a few
 * seconds to complete before the user will be able to see and connect
 * to the network.
 */
function startAP(ip) {
  return run(platform.startAP, {IP: ip});
}

/**
 * Like startAP(), but take the access point down, using platform-dependent
 * commands.
 *
 * Returns a promise that resolves when the commands have been run. At
 * this point, the AP should be in the process of stopping but may not
 * yet be completely down.
 */
function stopAP() {
  return run(platform.stopAP);
}

/**
 * This function uses wpa_cli to add the specified network ssid and password
 * to the wpa_supplicant.conf file. This assumes that wpa_supplicant is
 * configured to run automatically at boot time and is configured to work
 * with wpa_cli.
 *
 * If the system is not connected to a wifi network, calling this
 * command with a valid ssid and password should cause it to connect.
 */
function defineNetwork(ssid, password) {
  return run(password ? platform.defineNetwork : platform.defineOpenNetwork, {
    SSID: ssid,
    PSK: password,
  });
}

/**
 * This function uses wpa_cli to remove the network with the given ID.
 */
function removeNetwork(id) {
  return run(platform.removeNetwork, {ID: id});
}

/**
 * Return a Promise that resolves to an array of known wifi network names
 */
function getKnownNetworks() {
  return run(platform.getKnownNetworks)
    .then((out) => out.length ? out.split('\n') : []);
}

/**
 * Broadcast a Bluetooth Eddystone beacon with the local IP address.
 */
function broadcastBeacon() {
  let cmd = platform.broadcastBeacon;

  let ip = null;
  const ifaces = os.networkInterfaces();

  // Check out wlan0 first.
  if (ifaces.hasOwnProperty('wlan0')) {
    for (const addr of ifaces.wlan0) {
      if (addr.family !== 'IPv4' || addr.internal) {
        continue;
      }

      ip = addr.address;
      break;
    }
  }

  // If we didn't get an IP address, check out eth0.
  if (ip === null && ifaces.hasOwnProperty('eth0')) {
    for (const addr of ifaces.eth0) {
      if (addr.family !== 'IPv4' || addr.internal) {
        continue;
      }

      ip = addr.address;
      break;
    }
  }

  // If we still don't have an IP, bail.
  if (ip === null) {
    // Don't reject, as this isn't really critical.
    return Promise.resolve();
  }

  // OGF + OCF
  cmd += ' 0x08 0x0008';

  // Length byte
  const length1 = 14 + ip.length;
  cmd += ` ${length1.toString(16)}`;

  // Flags
  cmd += ' 02 01 06';

  // UUIDs
  cmd += ' 03 03 aa fe';

  // Length byte
  const length2 = 6 + ip.length;
  cmd += ` ${length2.toString(16)}`;

  // Service data type value
  cmd += ' 16';

  // UUIDs
  cmd += ' aa fe';

  // Frame type
  cmd += ' 10';

  // TX power
  cmd += ' 00';

  // URL scheme
  cmd += ' 02';

  // URL
  cmd += ` ${ip.split('').map((x) => x.charCodeAt(0).toString(16)).join(' ')}`;

  // Trailer
  cmd += ' 00 00 00 00 00 00 00 00';

  return run(cmd);
}

function checkConnection() {
  if (fs.existsSync('wifiskip')) {
    return Promise.resolve(true);
  }
  return getStatus().then(() => {
    // Wait until we have a working wifi connection. Retry every 3 seconds up
    // to 10 times. If we are connected, then start the Gateway client.
    // If we never get a wifi connection, go into AP mode.
    // Before we start, though, let the user know that something is happening
    return waitForWiFi(20, 3000).then(() => {
      return true;
    }).catch((err) => {
      console.log('No wifi connection found. Starting the AP...', err);
      // Scan for wifi networks now because we can't always scan once
      // the AP is being broadcast, retrying up to 10 times
      scan(10).then((ssids) => {
        exports.preliminaryScanResults = ssids; // Remember ssids
        console.log('No wifi found; entering AP mode');
        startAP(platform.ap_ip);
      });

      return false;
    });
  }).catch((err) => {
    console.error('Error checking wifi adapter presence', err);
    return true;
  });
}

// Return a promise, then check every interval ms for a wifi connection.
// Resolve the promise when we're connected. Or, if we aren't connected
// after maxAttempts attempts, then reject the promise
function waitForWiFi(maxAttempts, interval) {
  return new Promise(function(resolve, reject) {
    let attempts = 0;

    // first of all we query wpa_supplicant if there's a wifi AP configured
    run(platform.listNetworks)
      .then((out) => {
        console.log('List Networks command executed:', out);
        if (out.includes('\n0\t')) {
          // there's at least one wifi AP configured. Let's wait to see if it
          // will connect
          check();
        } else {
          // No wifi AP configured. Let's skip the wait and start the setup
          // immediately
          reject();
        }
      })
      .catch((err) => console.error('Error listing Networks:', err));

    function check() {
      attempts++;
      console.log('check', attempts);
      getStatus()
        .then((status) => {
          console.log(status);
          if (status === 'COMPLETED') {
            console.log('WiFi connection found. resolving');
            checkForAddress();
            console.log('resolved');
          } else {
            console.log('No wifi connection on attempt', attempts);
            retryOrGiveUp();
          }
        })
        .catch((err) => {
          console.error('Error checking wifi on attempt', attempts, ':', err);
          retryOrGiveUp();
        });
    }

    function checkForAddress() {
      const ifaces = os.networkInterfaces();

      if (ifaces.hasOwnProperty('wlan0')) {
        for (const addr of ifaces.wlan0) {
          if (addr.family !== 'IPv4' || addr.internal) {
            continue;
          }

          resolve();
          return;
        }
      }

      retryOrGiveUp();
    }

    function retryOrGiveUp() {
      if (attempts >= maxAttempts) {
        console.error('Giving up. No wifi available.');
        reject();
      } else {
        setTimeout(check, interval);
      }
    }
  });
}
<|endoftext|>


<commit_before>Class("Joose.TypeConstraint", {
    has: {
        _constraints: {
            is: "ro",
            init: function () { return [] }
        },
        _coercions: {
            is: "ro",
            init: function () { return [] }
        },
        _messages: {
            is: "ro",
            init: function () { return [] }
        },
        _name: {
            is: "ro"
        },
        _uses: {
            is: "ro",
        },
    },

    classMethods: {
        newFromTypeBuilder: function (name, props) {
            var t = new Joose.TypeConstraint({ name: name });
            if ( props.isa
                 && typeof props.isa.meta != 'undefined'
                 && props.isa.meta.isa(Joose.TypeConstraint) ) {
                 t._uses = props.isa;
                 //t = props.isa.makeSubType(name);

            } else {
            }

            if(props.where) {
                t.addConstraint(props.where)
            }

            if(props.coerce) {
                for(var i = 0; i < props.coerce.length; i++) {
                    var coercionProps = props.coerce[i];
                    t.addCoercion(new Joose.TypeCoercion({
                        from: coercionProps.from,
                        via:  coercionProps.via
                    }))
                }
            }

            return t
        }
    },

    methods: {

        stringify: function () {
            return this._name
        },

        makeSubType: function (name) {
            var t = new Joose.TypeConstraint({ name: name })
            Joose.A.each(this._constraints, function (con) {
                t.addConstraint(con)
            })
            return t
        },

        addCoercion: function (coercion) {
            this._coercions.push(coercion);
        },

        addConstraint: function (func, message) {
            this._constraints.push(func);
            this._messages.push(message)
        },

        getConstraintList: function () {
            var cons = this._constraints;
            if ( this._uses ) {
                var parentcons = this._uses.getConstraintList();
                return cons.concat(parentcons);
            }
            return cons;
        },

        validateBool: function (value) {
            var i = this._validate(value);
            if(i == -1) {
                return true
            }
            return false
        },

        validate: function (value) {
            var i = this._validate(value);
            if(i == -1) {
                return true
            }
            var message = this._messages[i];
            if(message) {
                throw new ReferenceError(message.apply(this, value))
            }
            throw new ReferenceError("The passed value ["+value+"] is not a "+this)
        },

        _validate: function (value) {
            var con = this.getConstraintList();
            var i, len;
            for(i = 0, len = con.length; i < len; i++) {
                var func = con[i];
                var result = false;
                if(func instanceof RegExp) {
                    result = func.test(value)
                } else {
                    result = func.call(this, value)
                }

                if(!result) {
                    return i

                }
            }
            return -1
        },

        coerce: function (value) {
            if(this.validateBool(value)) {
                return value
            }
            //alert("in constraints coerce call: "+value);
            var coercions = this._coercions;
            for(var i = 0, len = coercions.length; i < len; i++) {
                var coercion = coercions[i];
                var result   = coercion.coerce(value);
                if(result != null) {
                    return result
                }
            }
            return null
        }
    }
});

Type('Any', {
    where: function(o) {
        if ( typeof o != 'undefined' ) {
            return true;
        }
        return false;
    }
});

Type('Null', {
    isa: TYPE.Any,
    where: function(o) {
    }
});

Type('Obj', {
    isa: TYPE.Any,
    where: function (o) {
        if ( o instanceof Object ) {
            return true;
        }
        return false;
    }
});

Type('Num', {
    //isa: Type.Any,
    where: function(n) {
    }
});

Type('Int', {
    //isa: Type.Num,
    where: function(n) {
    }
});

Type('Float', {
    //isa: Type.Num,
    where: function(n) {
    }
});

Type('Str', {
    //isa: Type.Any,
    where: function(S) {
    }
});

Type('Bool', {
    //isa: Type.Any,
    where: function(S) {
    }
});

Type('Func', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Array', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Literal', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('ArrayLiteral', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('ObjectLiteral', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Joose', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

<commit_msg>fixed the concatenation order of the constraints in getConstraintList<commit_after>Class("Joose.TypeConstraint", {
    has: {
        _constraints: {
            is: "ro",
            init: function () { return [] }
        },
        _coercions: {
            is: "ro",
            init: function () { return [] }
        },
        _messages: {
            is: "ro",
            init: function () { return [] }
        },
        _name: {
            is: "ro"
        },
        _uses: {
            is: "ro",
        },
    },

    classMethods: {
        newFromTypeBuilder: function (name, props) {
            var t = new Joose.TypeConstraint({ name: name });
            if ( props.isa
                 && typeof props.isa.meta != 'undefined'
                 && props.isa.meta.isa(Joose.TypeConstraint) ) {
                 t._uses = props.isa;
                 //t = props.isa.makeSubType(name);

            } else {
            }

            if(props.where) {
                t.addConstraint(props.where)
            }

            if(props.coerce) {
                for(var i = 0; i < props.coerce.length; i++) {
                    var coercionProps = props.coerce[i];
                    t.addCoercion(new Joose.TypeCoercion({
                        from: coercionProps.from,
                        via:  coercionProps.via
                    }))
                }
            }

            return t
        }
    },

    methods: {

        stringify: function () {
            return this._name
        },

        makeSubType: function (name) {
            var t = new Joose.TypeConstraint({ name: name })
            Joose.A.each(this._constraints, function (con) {
                t.addConstraint(con)
            })
            return t
        },

        addCoercion: function (coercion) {
            this._coercions.push(coercion);
        },

        addConstraint: function (func, message) {
            this._constraints.push(func);
            this._messages.push(message)
        },

        getConstraintList: function () {
            var cons = this._constraints;
            if ( this._uses ) {
                var parentcons = this._uses.getConstraintList();
                return parentcons.concat(cons);
            }
            return cons;
        },

        validateBool: function (value) {
            var i = this._validate(value);
            if(i == -1) {
                return true
            }
            return false
        },

        validate: function (value) {
            var i = this._validate(value);
            if(i == -1) {
                return true
            }
            var message = this._messages[i];
            if(message) {
                throw new ReferenceError(message.apply(this, value))
            }
            throw new ReferenceError("The passed value ["+value+"] is not a "+this)
        },

        _validate: function (value) {
            var con = this.getConstraintList();
            var i, len;
            for(i = 0, len = con.length; i < len; i++) {
                var func = con[i];
                var result = false;
                if(func instanceof RegExp) {
                    result = func.test(value)
                } else {
                    result = func.call(this, value)
                }

                if(!result) {
                    return i

                }
            }
            return -1
        },

        coerce: function (value) {
            if(this.validateBool(value)) {
                return value
            }
            //alert("in constraints coerce call: "+value);
            var coercions = this._coercions;
            for(var i = 0, len = coercions.length; i < len; i++) {
                var coercion = coercions[i];
                var result   = coercion.coerce(value);
                if(result != null) {
                    return result
                }
            }
            return null
        }
    }
});

Type('Any', {
    where: function(o) {
        if ( typeof o != 'undefined' ) {
            return true;
        }
        return false;
    }
});

Type('Null', {
    isa: TYPE.Any,
    where: function(o) {
    }
});

Type('Obj', {
    isa: TYPE.Any,
    where: function (o) {
        if ( o instanceof Object ) {
            return true;
        }
        return false;
    }
});

Type('Num', {
    //isa: Type.Any,
    where: function(n) {
    }
});

Type('Int', {
    //isa: Type.Num,
    where: function(n) {
    }
});

Type('Float', {
    //isa: Type.Num,
    where: function(n) {
    }
});

Type('Str', {
    //isa: Type.Any,
    where: function(S) {
    }
});

Type('Bool', {
    //isa: Type.Any,
    where: function(S) {
    }
});

Type('Func', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Array', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Literal', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('ArrayLiteral', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('ObjectLiteral', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

Type('Joose', {
    //isa: Type.Obj,
    where: function (f) {
    }
});

<|endoftext|>


<commit_before>import React, { useCallback, useRef, useState } from "react";
import styled from "styled-components";
import PropTypes from "prop-types";
import { InfosElu } from "@agir/elus/parrainages/types";
import {
  DECISIONS,
  ELU_STATUTS,
  ISSUE,
  RequestStatus,
  StatutPill,
} from "./types";
import Button from "@agir/front/genericComponents/Button";
import { creerRechercheParrainage, terminerParrainage } from "./queries";
import AnimatedMoreHorizontal from "../../../front/components/genericComponents/AnimatedMoreHorizontal";

const Presentation = () => (

Collecte des parrainages

      Interface d’organisation pour l’obtention des 500 signatures pour la
      candidature de Jean-Luc Mélenchon aux présidentielles de 2022.

        Choisissez un⋅e élu⋅e disponible, c'est-à-dire que personne d'autre n'a
        encore prévu de contacter

        Confirmez que vous comptez le ou la contacter. Ce sera votre
        responsabilité !

        Une fois que vous aurez rencontré l'élu, n'oubliez pas de nous indiquer
        la conclusion de l'échange dans cette même interface

);

const HorairesList = styled.ul`
  list-style-type: none;
  margin: 0;
  padding: 0;
`;

const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);

const Horaires = ({ horaires }) => {
  return (
    <HorairesList>
      {horaires.map(([j1, j2, hs]) => {
        const jours = j1 === j2 ? capitalize(j1) : `${capitalize(j1)} au ${j2}`;
        const heures = hs
          .map(([h1, h2]) => `${h1.slice(0, 5)} — ${h2.slice(0, 5)}`)
          .join(" et ");
        return (

            {jours} : {heures}

        );
      })}
    </HorairesList>
  );
};
Horaires.propTypes = {
  horaires: PropTypes.array,
};

const Block = styled.div`
  margin: 24px 0;
`;

const Error = styled.div`
  color: ${(props) => props.theme.redNSP};
  font-weight: 500;
`;

const CadreAvertissement = styled.div`
  background-color: ${(props) => props.theme.black50};
  margin: 20px 0;
  padding: 1rem;
`;

const BoutonCreerParrainage = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const callback = useCallback(async () => {
    setState(RequestStatus.LOADING());
    try {
      const res = await creerRechercheParrainage(elu.id);
      setState(RequestStatus.IDLE());
      onStatusChange({
        ...elu,
        statut: ELU_STATUTS.A_CONTACTER,
        idRechercheParrainage: res.id,
      });
    } catch (e) {
      setState(RequestStatus.ERROR(e.message));
    }
  }, [elu, onStatusChange]);

  return (

      <Button color="primary" onClick={callback} disabled={state.isLoading}>
        Je m'en occupe !
      </Button>
      {state.isLoading && <AnimatedMoreHorizontal />}
      {state.isError && <Error>{state.message}</Error>}

  );
};
BoutonCreerParrainage.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const BoutonAnnuler = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const annuler = useCallback(async () => {
    try {
      setState(RequestStatus.LOADING());
      await terminerParrainage(elu.idRechercheParrainage, {
        statut: ISSUE.ANNULE,
      });
      onStatusChange({
        ...elu,
        idRechercheParrainage: null,
        statut: ELU_STATUTS.DISPONIBLE,
      });
      setState(RequestStatus.IDLE());
    } catch (e) {
      setState(RequestStatus.ERROR(e.message));
    }
  }, [elu, onStatusChange]);

  return (
    <>
       {
          e.preventDefault();
          if (!state.isLoading) {
            annuler();
          }
        }}
      >
        Annuler le contact

      {state.isLoading && <AnimatedMoreHorizontal />}
      {state.isError && <Error>{state.message}</Error>}
    </>
  );
};

BoutonAnnuler.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const FormulaireTerminerParrainage = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const [decision, setDecision] = useState(null);
  const formulaireInput = useRef();
  const commentairesInput = useRef();

  const soumettreFormulaire = useCallback(
    async (e) => {
      e.preventDefault();
      setState(RequestStatus.LOADING());

      const formulaire =
        decision &&
        decision.formulaire &&
        formulaireInput.current.files.length > 0
          ? formulaireInput.current.files[0]
          : null;

      const commentaires = commentairesInput.value;

      try {
        await terminerParrainage(elu.idRechercheParrainage, {
          statut: decision ? ISSUE.ENGAGEMENT : ISSUE.REFUSE,
          commentaires,
          formulaire,
        });
        setState(RequestStatus.IDLE());
        onStatusChange({
          ...elu,
          statut: ELU_STATUTS.PERSONNELLEMENT_VU,
        });
      } catch (e) {
        setState(RequestStatus.ERROR(e.message));
      }
    },
    [elu, decision, onStatusChange]
  );

  return (

      <BoutonAnnuler elu={elu} onStatusChange={onStatusChange} />
      <CadreAvertissement>

          Contactez {elu.nomComplet} à propos de la signature
          de parrainage des élu⋅es pour la candidature de Jean-Luc Mélenchon.

          Conseil : Utilisez la documentation pour vous aider
          dans votre discours. Déplacez-vous en mairie pour
          obtenir de meilleurs résultats, le téléphone est généralement
          insuffisant

      </CadreAvertissement>
      <form onSubmit={soumettreFormulaire}>

Conclusion de l'échange

        {DECISIONS.map((d) => (

            <input
              type="radio"
              name="statut"
              id={d.id}
              checked={decision && d.id === decision.id}
              onChange={() => setDecision(d)}
            />{" "}
            {d.label}

        ))}

          {(decision && decision.commentairesTitre) || "Commentaires"}

        <textarea
          id="commentaires"
          name="commentaires"
          ref={commentairesInput}
          required={decision && decision.commentairesRequis}
        />

        {decision && decision.formulaire && (
          <>

              Formulaire signé

            <input
              id="formulaire"
              type="file"
              name="formulaire"
              ref={formulaireInput}
              required={true}
            />
          </>
        )}
        <Button
          color="primary"
          disabled={state.isLoading || decision === null}
          block={true}
        >
          Envoyer les informations
        </Button>
        {state.isLoading && <AnimatedMoreHorizontal />}
        {state.isError && <Error>{state.message}</Error>}
      </form>

  );
};

FormulaireTerminerParrainage.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const InteractionBoxLayout = styled(Block)`
  border: 1px solid ${(props) => props.theme.black200};
  padding: 20px;
`;

const InteractionBox = ({ elu, onStatusChange }) => {
  const demonstratif = elu.sexe === "F" ? "cette élue" : "cet élu";

  switch (elu.statut) {
    case "D":
      return (
        <InteractionBoxLayout>

Personne n'a indiqué s'occuper de {demonstratif}.

          <BoutonCreerParrainage elu={elu} onStatusChange={onStatusChange} />
        </InteractionBoxLayout>
      );
    case "E":
      return (
        <InteractionBoxLayout>
          Quelqu'un d'autre a indiqué s'occuper de contacter {demonstratif}
          👍
        </InteractionBoxLayout>
      );
    case "A":
      return (
        <InteractionBoxLayout>
          <FormulaireTerminerParrainage
            elu={elu}
            onStatusChange={onStatusChange}
          />
        </InteractionBoxLayout>
      );
    case "T":
      return (
        <InteractionBoxLayout>
          Quelqu'un d'autre s'est déjà chargé de contacter {demonstratif}
        </InteractionBoxLayout>
      );
    case "P":
      return (
        <InteractionBoxLayout>
          Merci de vous être occupé⋅e de contacter cette personne 🚀
        </InteractionBoxLayout>
      );
  }
};
InteractionBox.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const Layout = styled.div`
  padding: 60px;

  @media (max-width: ${(props) => props.theme.collapse}px) {
    padding: 0 35px;
  }

  ${Block} {
    font-size: 16px;
  }

  h2 {
    margin-bottom: 0.5rem;
  }
  .subtitle {
    font-size: 16px;
    margin-bottom: 30px;
  }

  h3 {
    margin-bottom: 0;
  }

  label {
    display: block;
    margin: 0;
    font-weight: 400;
  }

  label.title,
  h4 {
    font-weight: 700;
    font-size: 14px;
    margin: 20px 0 8px;
  }

  ${Button} {
    margin: 11px 0;
  }
`;

const Container = styled.div`
  margin: 0 auto;
  max-width: 600px;
`;

const FicheElu = ({ elu, onStatusChange }) => {
  if (elu === null || elu === undefined) {
    return (
      <Layout>
        <Container>
          <Presentation />
        </Container>
      </Layout>
    );
  }

  const mairie = elu.mairie;
  const distance = elu.distance.toLocaleString("fr-FR", {
    maximumFractionDigits: 1,
  });

  return (
    <Layout>
      <Container>

{elu.nomComplet}

          {elu.titre} — {elu.commune}{" "}
          {elu.distance > 0.1 && `(à ${distance} km)`}

        <Block>
          <StatutPill statut={elu.statut} />
        </Block>
        <InteractionBox elu={elu} onStatusChange={onStatusChange} />
        {mairie.adresse && (
          <Block>

Adresse de la mairie

{mairie.adresse}

          </Block>
        )}
        {mairie.telephone && (
          <Block>

Numéro de téléphone de la mairie

{mairie.telephone}

          </Block>
        )}
        {mairie.email && (
          <Block>

Adresse email de la mairie

              <a
                href={
                  mairie.email.match(/https?:\/\//)
                    ? mairie.email
                    : `mailto:${mairie.email}`
                }
              >
                {mairie.email}

          </Block>
        )}
        {mairie.horaires && mairie.horaires.length !== 0 && (
          <Block>

Horaires d'ouverture de la mairie

            <Horaires horaires={mairie.horaires} />
          </Block>
        )}
      </Container>
    </Layout>
  );
};

FicheElu.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};
FicheElu.Layout = Layout;

export default FicheElu;
<commit_msg>fix(parrainages): envoyer les bonnes valeurs<commit_after>import React, { useCallback, useRef, useState } from "react";
import styled from "styled-components";
import PropTypes from "prop-types";
import { InfosElu } from "@agir/elus/parrainages/types";
import {
  DECISIONS,
  ELU_STATUTS,
  ISSUE,
  RequestStatus,
  StatutPill,
} from "./types";
import Button from "@agir/front/genericComponents/Button";
import { creerRechercheParrainage, terminerParrainage } from "./queries";
import AnimatedMoreHorizontal from "../../../front/components/genericComponents/AnimatedMoreHorizontal";

const Presentation = () => (

Collecte des parrainages

      Interface d’organisation pour l’obtention des 500 signatures pour la
      candidature de Jean-Luc Mélenchon aux présidentielles de 2022.

        Choisissez un⋅e élu⋅e disponible, c'est-à-dire que personne d'autre n'a
        encore prévu de contacter

        Confirmez que vous comptez le ou la contacter. Ce sera votre
        responsabilité !

        Une fois que vous aurez rencontré l'élu, n'oubliez pas de nous indiquer
        la conclusion de l'échange dans cette même interface

);

const HorairesList = styled.ul`
  list-style-type: none;
  margin: 0;
  padding: 0;
`;

const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);

const Horaires = ({ horaires }) => {
  return (
    <HorairesList>
      {horaires.map(([j1, j2, hs]) => {
        const jours = j1 === j2 ? capitalize(j1) : `${capitalize(j1)} au ${j2}`;
        const heures = hs
          .map(([h1, h2]) => `${h1.slice(0, 5)} — ${h2.slice(0, 5)}`)
          .join(" et ");
        return (

            {jours} : {heures}

        );
      })}
    </HorairesList>
  );
};
Horaires.propTypes = {
  horaires: PropTypes.array,
};

const Block = styled.div`
  margin: 24px 0;
`;

const Error = styled.div`
  color: ${(props) => props.theme.redNSP};
  font-weight: 500;
`;

const CadreAvertissement = styled.div`
  background-color: ${(props) => props.theme.black50};
  margin: 20px 0;
  padding: 1rem;
`;

const BoutonCreerParrainage = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const callback = useCallback(async () => {
    setState(RequestStatus.LOADING());
    try {
      const res = await creerRechercheParrainage(elu.id);
      setState(RequestStatus.IDLE());
      onStatusChange({
        ...elu,
        statut: ELU_STATUTS.A_CONTACTER,
        idRechercheParrainage: res.id,
      });
    } catch (e) {
      setState(RequestStatus.ERROR(e.message));
    }
  }, [elu, onStatusChange]);

  return (

      <Button color="primary" onClick={callback} disabled={state.isLoading}>
        Je m'en occupe !
      </Button>
      {state.isLoading && <AnimatedMoreHorizontal />}
      {state.isError && <Error>{state.message}</Error>}

  );
};
BoutonCreerParrainage.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const BoutonAnnuler = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const annuler = useCallback(async () => {
    try {
      setState(RequestStatus.LOADING());
      await terminerParrainage(elu.idRechercheParrainage, {
        statut: ISSUE.ANNULE,
      });
      onStatusChange({
        ...elu,
        idRechercheParrainage: null,
        statut: ELU_STATUTS.DISPONIBLE,
      });
      setState(RequestStatus.IDLE());
    } catch (e) {
      setState(RequestStatus.ERROR(e.message));
    }
  }, [elu, onStatusChange]);

  return (
    <>
       {
          e.preventDefault();
          if (!state.isLoading) {
            annuler();
          }
        }}
      >
        Annuler le contact

      {state.isLoading && <AnimatedMoreHorizontal />}
      {state.isError && <Error>{state.message}</Error>}
    </>
  );
};

BoutonAnnuler.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const FormulaireTerminerParrainage = ({ elu, onStatusChange }) => {
  const [state, setState] = useState(RequestStatus.IDLE());
  const [decision, setDecision] = useState(null);
  const formulaireInput = useRef();
  const commentairesInput = useRef();

  const soumettreFormulaire = useCallback(
    async (e) => {
      e.preventDefault();
      setState(RequestStatus.LOADING());

      const formulaire =
        decision &&
        decision.formulaire &&
        formulaireInput.current.files.length > 0
          ? formulaireInput.current.files[0]
          : null;

      const commentaires = commentairesInput.current.value;

      try {
        await terminerParrainage(elu.idRechercheParrainage, {
          statut: decision.value,
          commentaires,
          formulaire,
        });
        setState(RequestStatus.IDLE());
        onStatusChange({
          ...elu,
          statut: ELU_STATUTS.PERSONNELLEMENT_VU,
        });
      } catch (e) {
        setState(RequestStatus.ERROR(e.message));
      }
    },
    [elu, decision, onStatusChange]
  );

  return (

      <BoutonAnnuler elu={elu} onStatusChange={onStatusChange} />
      <CadreAvertissement>

          Contactez {elu.nomComplet} à propos de la signature
          de parrainage des élu⋅es pour la candidature de Jean-Luc Mélenchon.

          Conseil : Utilisez la documentation pour vous aider
          dans votre discours. Déplacez-vous en mairie pour
          obtenir de meilleurs résultats, le téléphone est généralement
          insuffisant

      </CadreAvertissement>
      <form onSubmit={soumettreFormulaire}>

Conclusion de l'échange

        {DECISIONS.map((d) => (

            <input
              type="radio"
              name="statut"
              id={d.id}
              checked={decision && d.id === decision.id}
              onChange={() => setDecision(d)}
            />{" "}
            {d.label}

        ))}

          {(decision && decision.commentairesTitre) || "Commentaires"}

        <textarea
          id="commentaires"
          name="commentaires"
          ref={commentairesInput}
          required={decision && decision.commentairesRequis}
        />

        {decision && decision.formulaire && (
          <>

              Formulaire signé

            <input
              id="formulaire"
              type="file"
              name="formulaire"
              ref={formulaireInput}
              required={true}
            />
          </>
        )}
        <Button
          color="primary"
          disabled={state.isLoading || decision === null}
          block={true}
        >
          Envoyer les informations
        </Button>
        {state.isLoading && <AnimatedMoreHorizontal />}
        {state.isError && <Error>{state.message}</Error>}
      </form>

  );
};

FormulaireTerminerParrainage.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const InteractionBoxLayout = styled(Block)`
  border: 1px solid ${(props) => props.theme.black200};
  padding: 20px;
`;

const InteractionBox = ({ elu, onStatusChange }) => {
  const demonstratif = elu.sexe === "F" ? "cette élue" : "cet élu";

  switch (elu.statut) {
    case "D":
      return (
        <InteractionBoxLayout>

Personne n'a indiqué s'occuper de {demonstratif}.

          <BoutonCreerParrainage elu={elu} onStatusChange={onStatusChange} />
        </InteractionBoxLayout>
      );
    case "E":
      return (
        <InteractionBoxLayout>
          Quelqu'un d'autre a indiqué s'occuper de contacter {demonstratif}
          👍
        </InteractionBoxLayout>
      );
    case "A":
      return (
        <InteractionBoxLayout>
          <FormulaireTerminerParrainage
            elu={elu}
            onStatusChange={onStatusChange}
          />
        </InteractionBoxLayout>
      );
    case "T":
      return (
        <InteractionBoxLayout>
          Quelqu'un d'autre s'est déjà chargé de contacter {demonstratif}
        </InteractionBoxLayout>
      );
    case "P":
      return (
        <InteractionBoxLayout>
          Merci de vous être occupé⋅e de contacter cette personne 🚀
        </InteractionBoxLayout>
      );
  }
};
InteractionBox.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};

const Layout = styled.div`
  padding: 60px;

  @media (max-width: ${(props) => props.theme.collapse}px) {
    padding: 0 35px;
  }

  ${Block} {
    font-size: 16px;
  }

  h2 {
    margin-bottom: 0.5rem;
  }
  .subtitle {
    font-size: 16px;
    margin-bottom: 30px;
  }

  h3 {
    margin-bottom: 0;
  }

  label {
    display: block;
    margin: 0;
    font-weight: 400;
  }

  label.title,
  h4 {
    font-weight: 700;
    font-size: 14px;
    margin: 20px 0 8px;
  }

  ${Button} {
    margin: 11px 0;
  }
`;

const Container = styled.div`
  margin: 0 auto;
  max-width: 600px;
`;

const FicheElu = ({ elu, onStatusChange }) => {
  if (elu === null || elu === undefined) {
    return (
      <Layout>
        <Container>
          <Presentation />
        </Container>
      </Layout>
    );
  }

  const mairie = elu.mairie;
  const distance = elu.distance.toLocaleString("fr-FR", {
    maximumFractionDigits: 1,
  });

  return (
    <Layout>
      <Container>

{elu.nomComplet}

          {elu.titre} — {elu.commune}{" "}
          {elu.distance > 0.1 && `(à ${distance} km)`}

        <Block>
          <StatutPill statut={elu.statut} />
        </Block>
        <InteractionBox elu={elu} onStatusChange={onStatusChange} />
        {mairie.adresse && (
          <Block>

Adresse de la mairie

{mairie.adresse}

          </Block>
        )}
        {mairie.telephone && (
          <Block>

Numéro de téléphone de la mairie

{mairie.telephone}

          </Block>
        )}
        {mairie.email && (
          <Block>

Adresse email de la mairie

              <a
                href={
                  mairie.email.match(/https?:\/\//)
                    ? mairie.email
                    : `mailto:${mairie.email}`
                }
              >
                {mairie.email}

          </Block>
        )}
        {mairie.horaires && mairie.horaires.length !== 0 && (
          <Block>

Horaires d'ouverture de la mairie

            <Horaires horaires={mairie.horaires} />
          </Block>
        )}
      </Container>
    </Layout>
  );
};

FicheElu.propTypes = {
  elu: InfosElu,
  onStatusChange: PropTypes.func,
};
FicheElu.Layout = Layout;

export default FicheElu;
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var App = require('app');

module.exports = App.WizardRoute.extend({
  route: '/enable',
  breadcrumbs: null,
  enter: function (router) {
    router.get('mainController').dataLoading().done(function() {
      return App.clusterStatus.updateFromServer();
    }).done(function () {
      var kerberosWizardController = router.get('kerberosWizardController');
      App.router.get('updateController').set('isWorking', false);
      var popup = App.ModalPopup.show({
        classNames: ['wizard-modal-wrapper'],
        modalDialogClasses: ['modal-xlg'],
        header: Em.I18n.t('admin.kerberos.wizard.header'),
        bodyClass: App.KerberosWizardView.extend({
          controller: kerberosWizardController
        }),
        primary: Em.I18n.t('form.cancel'),
        showFooter: false,
        secondary: null,

        onClose: function () {
          var self = this;
          switch (kerberosWizardController.get('currentStep')) {
            case "2":
              var step2Controller = router.get('kerberosWizardStep2Controller');
              if (step2Controller.get('testConnectionInProgress')) {
                step2Controller.showConnectionInProgressPopup(function () {
                  kerberosWizardController.warnBeforeExitPopup(function () {
                    self.exitWizard();
                  }, false);
                });
              } else {
                kerberosWizardController.warnBeforeExitPopup(function () {
                  self.exitWizard();
                }, false);
              }
              break;
            case "6":
            case "7":
              kerberosWizardController.warnBeforeExitPopup(function () {
                self.exitWizard();
              }, true);
              break;
            default:
              kerberosWizardController.warnBeforeExitPopup(function () {
                self.exitWizard();
              }, false);
          }
        },
        didInsertElement: function () {
          this._super();
          this.fitHeight();
        },

        exitWizard: function () {
          var kerberosProgressPageController = App.router.get('kerberosProgressPageController');
          var controller = App.router.get('kerberosWizardController');
          var exitPath = controller.getDBProperty('onClosePath') || 'adminKerberos.index';
          controller.clearTasksData();
          controller.discardChanges().then(function() {
            if (App.get('testMode')) {
              App.get('router').transitionTo('adminKerberos.index');
              Em.run.next(function() {
                location.reload();
              });
            }
            controller.resetOnClose(controller, exitPath);
          });
        }
      });
      kerberosWizardController.set('popup', popup);
      var currentClusterStatus = App.clusterStatus.get('value');
      if (currentClusterStatus) {
        if (App.get('testMode')) {
          kerberosWizardController.setCurrentStep(App.db.data.KerberosWizard.currentStep);
        } else {
          switch (currentClusterStatus.clusterState) {
            case 'KERBEROS_DEPLOY' :
              kerberosWizardController.setCurrentStep(currentClusterStatus.localdb.KerberosWizard.currentStep);
              break;
            default:
              var currStep = App.get('router.kerberosWizardController.currentStep');
              kerberosWizardController.setCurrentStep(currStep);
              break;
          }
        }

      }
      Em.run.next(function(){
        App.router.get('wizardWatcherController').setUser(kerberosWizardController.get('name'));
        router.transitionTo('step' + kerberosWizardController.get('currentStep'));
      });
    });
  },

  step1: App.StepRoute.extend({
    route: '/step1',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('1');
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep1', controller.get('content'));
        });
      });
    },

    unroutePath: function () {
      return false;
    },

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var kerberosStep1controller = router.get('kerberosWizardStep1Controller');

      kerberosWizardController.saveKerberosOption(kerberosStep1controller);
      kerberosWizardController.clearServiceConfigProperties();
      router.transitionTo('step2');
    }
  }),

  step2: App.StepRoute.extend({
    route: '/step2',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('2');
        controller.loadAllPriorSteps().done(function() {
          var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
          kerberosWizardStep2Controller.set('wizardController', controller);
          controller.connectOutlet('kerberosWizardStep2', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: function(router) {
      var controller = router.get('kerberosWizardStep2Controller');
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.overrideVisibility(controller.get('configs'), true, []);
      router.transitionTo('step1');
    },

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');

      if (kerberosWizardController.get('skipClientInstall')) {
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'manage_identities').set('value', 'false');
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'install_packages').set('value', 'false');
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'manage_krb5_conf').set('value', 'false');
      }

      kerberosWizardController.saveServiceConfigProperties(kerberosWizardStep2Controller, true);
      kerberosWizardController.clearTasksData();
      if (kerberosWizardController.get('skipClientInstall')) {
        kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
        router.transitionTo('step4');
      } else {
        router.transitionTo('step3');
      }
    }
  }),

  step3: App.StepRoute.extend({
    route: '/step3',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('3');
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep3', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    back: Em.Router.transitionTo('step2'),
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
      kerberosWizardController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
      router.transitionTo('step4');
    }
  }),

  step4: App.StepRoute.extend({
    route: '/step4',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      var step4Controller = router.get('kerberosWizardStep4Controller');
      controller.setCurrentStep(4);
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('4');
        controller.loadAllPriorSteps().done(function() {
          controller.setLowerStepsDisable(4);
          step4Controller.set('wizardController', controller);
          controller.connectOutlet('kerberosWizardStep4', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: function (router) {
      if (router.get('kerberosWizardController.skipClientInstall')) {
        router.transitionTo('step2');
      } else {
        router.transitionTo('step3');
      }
    },
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var step5Controller = router.get('kerberosWizardStep5Controller');
      var kerberosDescriptor = kerberosWizardController.get('kerberosDescriptorConfigs');
      kerberosWizardController.cacheStepConfigValues(router.get('kerberosWizardStep4Controller'));
      step5Controller.postKerberosDescriptor(kerberosDescriptor).always(function (data, result) {
        if (result === 'error' && data.status === 409) {
          step5Controller.putKerberosDescriptor(kerberosDescriptor);
        } else {
          step5Controller.unkerberizeCluster();
        }
      });
    }
  }),

  step5: App.StepRoute.extend({
    route: '/step5',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('5');
        controller.setLowerStepsDisable(5);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
        });
      });
    },

    unroutePath: function () {
      return false;
    },

    exitWizard: function (router) {
      var popup = router.get('kerberosWizardController.popup');
      popup.onClose();
    },

    downloadCSV: function (router) {
      var kerberosWizardStep5Controller = router.get('kerberosWizardStep5Controller');
      kerberosWizardStep5Controller.getCSVData();
    },

    backTransition: Em.Router.transitionTo('step4'),

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperties({
        tasksStatuses: null,
        tasksRequestIds: null
      });
      router.transitionTo('step6');
    }
  }),

  step6: App.StepRoute.extend({
    route: '/step6',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('6');
        controller.setLowerStepsDisable(6);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep6', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step4'),
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperties({
        tasksStatuses: null,
        tasksRequestIds: null
      });
      router.transitionTo('step7');
    }
  }),

  step7: App.StepRoute.extend({
    route: '/step7',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      var step7Controller = router.get('kerberosWizardStep7Controller');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('7');
        controller.setLowerStepsDisable(7);
        controller.loadAllPriorSteps().done(function() {
          step7Controller.setRequest();
          controller.connectOutlet('kerberosWizardStep7', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step4'),
    nextTransition: function (router) {
      router.transitionTo('step8');
    }
  }),

  step8: App.StepRoute.extend({
    route: '/step8',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('8');
        controller.setLowerStepsDisable(8);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep8', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step7'),
    nextTransition: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.resetOnClose(controller, 'adminKerberos.index');
    }
  })
});
<commit_msg>AMBARI-22108 Dismissing Enable Kerberos wizard initiates Disable kerberos call. (atkach)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var App = require('app');

module.exports = App.WizardRoute.extend({
  route: '/enable',
  breadcrumbs: null,
  enter: function (router) {
    router.get('mainController').dataLoading().done(function() {
      return App.clusterStatus.updateFromServer();
    }).done(function () {
      var kerberosWizardController = router.get('kerberosWizardController');
      App.router.get('updateController').set('isWorking', false);
      var popup = App.ModalPopup.show({
        classNames: ['wizard-modal-wrapper'],
        modalDialogClasses: ['modal-xlg'],
        header: Em.I18n.t('admin.kerberos.wizard.header'),
        bodyClass: App.KerberosWizardView.extend({
          controller: kerberosWizardController
        }),
        primary: Em.I18n.t('form.cancel'),
        showFooter: false,
        secondary: null,

        onClose: function () {
          var self = this;
          switch (kerberosWizardController.get('currentStep')) {
            case "2":
              var step2Controller = router.get('kerberosWizardStep2Controller');
              if (step2Controller.get('testConnectionInProgress')) {
                step2Controller.showConnectionInProgressPopup(function () {
                  kerberosWizardController.warnBeforeExitPopup(function () {
                    self.exitWizard();
                  }, false);
                });
              } else {
                kerberosWizardController.warnBeforeExitPopup(function () {
                  self.exitWizard();
                }, false);
              }
              break;
            case "6":
            case "7":
              kerberosWizardController.warnBeforeExitPopup(function () {
                self.exitWizard();
              }, true);
              break;
            case "8":
              kerberosWizardController.warnBeforeExitPopup(function () {
                self.exitWizard(true);
              }, false);
              break;
            default:
              kerberosWizardController.warnBeforeExitPopup(function () {
                self.exitWizard();
              }, false);
          }
        },
        didInsertElement: function () {
          this._super();
          this.fitHeight();
        },

        exitWizard: function (skipDiscardChanges) {
          var controller = App.router.get('kerberosWizardController');
          var exitPath = controller.getDBProperty('onClosePath') || 'adminKerberos.index';
          controller.clearTasksData();
          if (skipDiscardChanges) {
            controller.resetOnClose(controller, exitPath);
          } else {
            controller.discardChanges().then(function() {
              controller.resetOnClose(controller, exitPath);
            });
          }
        }
      });
      kerberosWizardController.set('popup', popup);
      var currentClusterStatus = App.clusterStatus.get('value');
      if (currentClusterStatus) {
        if (App.get('testMode')) {
          kerberosWizardController.setCurrentStep(App.db.data.KerberosWizard.currentStep);
        } else {
          switch (currentClusterStatus.clusterState) {
            case 'KERBEROS_DEPLOY' :
              kerberosWizardController.setCurrentStep(currentClusterStatus.localdb.KerberosWizard.currentStep);
              break;
            default:
              var currStep = App.get('router.kerberosWizardController.currentStep');
              kerberosWizardController.setCurrentStep(currStep);
              break;
          }
        }

      }
      Em.run.next(function(){
        App.router.get('wizardWatcherController').setUser(kerberosWizardController.get('name'));
        router.transitionTo('step' + kerberosWizardController.get('currentStep'));
      });
    });
  },

  step1: App.StepRoute.extend({
    route: '/step1',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('1');
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep1', controller.get('content'));
        });
      });
    },

    unroutePath: function () {
      return false;
    },

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var kerberosStep1controller = router.get('kerberosWizardStep1Controller');

      kerberosWizardController.saveKerberosOption(kerberosStep1controller);
      kerberosWizardController.clearServiceConfigProperties();
      router.transitionTo('step2');
    }
  }),

  step2: App.StepRoute.extend({
    route: '/step2',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('2');
        controller.loadAllPriorSteps().done(function() {
          var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
          kerberosWizardStep2Controller.set('wizardController', controller);
          controller.connectOutlet('kerberosWizardStep2', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: function(router) {
      var controller = router.get('kerberosWizardStep2Controller');
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.overrideVisibility(controller.get('configs'), true, []);
      router.transitionTo('step1');
    },

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');

      if (kerberosWizardController.get('skipClientInstall')) {
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'manage_identities').set('value', 'false');
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'install_packages').set('value', 'false');
        kerberosWizardStep2Controller.get('stepConfigs')[0].get('configs').findProperty('name', 'manage_krb5_conf').set('value', 'false');
      }

      kerberosWizardController.saveServiceConfigProperties(kerberosWizardStep2Controller, true);
      kerberosWizardController.clearTasksData();
      if (kerberosWizardController.get('skipClientInstall')) {
        kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
        router.transitionTo('step4');
      } else {
        router.transitionTo('step3');
      }
    }
  }),

  step3: App.StepRoute.extend({
    route: '/step3',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('3');
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep3', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    back: Em.Router.transitionTo('step2'),
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
      kerberosWizardController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
      router.transitionTo('step4');
    }
  }),

  step4: App.StepRoute.extend({
    route: '/step4',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      var step4Controller = router.get('kerberosWizardStep4Controller');
      controller.setCurrentStep(4);
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('4');
        controller.loadAllPriorSteps().done(function() {
          controller.setLowerStepsDisable(4);
          step4Controller.set('wizardController', controller);
          controller.connectOutlet('kerberosWizardStep4', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: function (router) {
      if (router.get('kerberosWizardController.skipClientInstall')) {
        router.transitionTo('step2');
      } else {
        router.transitionTo('step3');
      }
    },
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      var step5Controller = router.get('kerberosWizardStep5Controller');
      var kerberosDescriptor = kerberosWizardController.get('kerberosDescriptorConfigs');
      kerberosWizardController.cacheStepConfigValues(router.get('kerberosWizardStep4Controller'));
      step5Controller.postKerberosDescriptor(kerberosDescriptor).always(function (data, result) {
        if (result === 'error' && data.status === 409) {
          step5Controller.putKerberosDescriptor(kerberosDescriptor);
        } else {
          step5Controller.unkerberizeCluster();
        }
      });
    }
  }),

  step5: App.StepRoute.extend({
    route: '/step5',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('5');
        controller.setLowerStepsDisable(5);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
        });
      });
    },

    unroutePath: function () {
      return false;
    },

    exitWizard: function (router) {
      var popup = router.get('kerberosWizardController.popup');
      popup.onClose();
    },

    downloadCSV: function (router) {
      var kerberosWizardStep5Controller = router.get('kerberosWizardStep5Controller');
      kerberosWizardStep5Controller.getCSVData();
    },

    backTransition: Em.Router.transitionTo('step4'),

    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperties({
        tasksStatuses: null,
        tasksRequestIds: null
      });
      router.transitionTo('step6');
    }
  }),

  step6: App.StepRoute.extend({
    route: '/step6',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('6');
        controller.setLowerStepsDisable(6);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep6', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step4'),
    nextTransition: function (router) {
      var kerberosWizardController = router.get('kerberosWizardController');
      kerberosWizardController.setDBProperties({
        tasksStatuses: null,
        tasksRequestIds: null
      });
      router.transitionTo('step7');
    }
  }),

  step7: App.StepRoute.extend({
    route: '/step7',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      var step7Controller = router.get('kerberosWizardStep7Controller');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('7');
        controller.setLowerStepsDisable(7);
        controller.loadAllPriorSteps().done(function() {
          step7Controller.setRequest();
          controller.connectOutlet('kerberosWizardStep7', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step4'),
    nextTransition: function (router) {
      router.transitionTo('step8');
    }
  }),

  step8: App.StepRoute.extend({
    route: '/step8',

    connectOutlets: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.dataLoading().done(function () {
        router.get('kerberosWizardController').setCurrentStep('8');
        controller.setLowerStepsDisable(8);
        controller.loadAllPriorSteps().done(function() {
          controller.connectOutlet('kerberosWizardStep8', controller.get('content'));
        });
      });
    },
    unroutePath: function () {
      return false;
    },
    backTransition: Em.Router.transitionTo('step7'),
    nextTransition: function (router) {
      var controller = router.get('kerberosWizardController');
      controller.resetOnClose(controller, 'adminKerberos.index');
    }
  })
});
<|endoftext|>


<commit_before>import curry from 'lodash/function/curry';
import getDisplayName from './getDisplayName';

const wrapDisplayName = (BaseComponent, hocName) => (
  `${hocName}(${getDisplayName(BaseComponent)})`
);

export default curry(wrapDisplayName);
<commit_msg>wrapDisplayName() doesn't need to be curried<commit_after>import getDisplayName from './getDisplayName';

const wrapDisplayName = (BaseComponent, hocName) => (
  `${hocName}(${getDisplayName(BaseComponent)})`
);

export default wrapDisplayName;
<|endoftext|>