<commit_before># Copyright (c) 2012 <NAME>. All rights reserved

import prelude


AdminModule = angular.module('AdminModule', [])



AdminModule.filter 'filterProp', ->
  (inputs, propName, textToMatch) ->
    [i for i in inputs when i[propName].search(textToMatch) >= 0]



AdminModule.factory 'AdminService', ['$http', ($http) ->

  pagesById = {}
  api = {}
  selectedPathsListeners = []

  api.selectPaths = (treesFoldersPageIds) ->
    for listener in selectedPathsListeners
      listener(treesFoldersPageIds)

  api.onPathSelectionChange = (listener) ->
    selectedPathsListeners.push listener

  api.getPageById = (pageId) ->
    if pagesById == {} then api.listAllPages -> 'noop'
    pagesById[pageId]

  api.listAllPages = (onSuccess) ->
    $http.get('/?list-pages.json&in-tree').success (data) ->
      # Angular has already parsed the JSON.
      for page in data.pages
        pagesById[page.id] = page
      onSuccess(data)

  api.listActions = (treesFoldersPageIds, onSuccess) ->
    treesStr   = treesFoldersPageIds.trees?.join(',') || ''
    foldersStr = treesFoldersPageIds.folders?.join(',') || ''
    pageIdsStr = treesFoldersPageIds.pageIds?.join(',') || ''
    $http.get("/?list-actions.json" +
        "&in-trees=#treesStr" +
        "&in-folders=#foldersStr" +
        "&for-pages=#pageIdsStr").success (data) ->
      onSuccess data

  actionsToJsonObjs = (actions) ->
    toJsonObj = (action) -> { pageId: action.pageId, actionId: action.id }
    map toJsonObj, actions

  api.approve = (actions, onSuccess) ->
    $http.post '/-/approve', actionsToJsonObjs(actions)
        .success -> onSuccess!

  api.reject = (actions, onSuccess) ->
    $http.post '/-/reject', actionsToJsonObjs(actions)
        .success -> onSuccess!

  api.delete = (actions, onSuccess) ->
    onSuccess! # for now

  api.createPage = (folder, callback) ->
    $http.post(folder + '?create-page',
        'page-title': 'Title'
        'page-slug': 'title'
        'show-id': true).success (data) ->
          callback data.newPage

  api

  ]



@PathsCtrl = ['$scope', 'AdminService', ($scope, adminService) ->

  allPages = []

  /**
   * Creates a new page and opens it in a new browser tab.
   */
  $scope.createPage = ->
    # Open new tab directly, in direct response to the user-initiated event,
    # or the browser's pop-up blocker tends to blocks it.
    newBrowserPage = window.open 'about:blank', '_blank'
    now = new Date!
    folder = '/' +
        padNumberToLength2(now.getFullYear!) + '/' +
        padNumberToLength2(now.getMonth!) + '/' +
        padNumberToLength2(now.getDate!) + '/'
    adminService.createPage folder, (newPage) ->
      newBrowserPage.location = newPage.path
      newPage.mark = 'New'
      allPages.push newPage
      listAllPages!

  isPage = (path) -> path.pageId?
  isFolder = (path) -> !isPage(path)
  depthOf = (path) ->
    matches = path.match(//(/[^/]*)//g)
    matches?.length || 0

  $scope.paths = []
  $scope.isPage = isPage
  $scope.isFolder = isFolder
  $scope.isFolderOrPageClass = (path) ->
    if isPage(path) then 'is-page' else 'is-folder'

  loadAndListPages = ->
    adminService.listAllPages (data) ->
      allPages := data.pages
      listAllPages!

  listAllPages = ->
      folderPathsDupl = []
      paths = []

      for page in allPages
        depth = depthOf page.path
        pagePath =
            pageId: page.id
            value: page.path # makePagePath folderPath, pageId, pageInfo
            displayPath: page.path # makePageDispPath folderPath, pageId, pageInfo
            title: page.title # pageInfo.title
            authors: page.authors
            included: false
            depth: depth
            open: false
            mark: page.mark
        paths.push pagePath
        folderPathsDupl.push page.folder

      folderPaths = unique folderPathsDupl
      folderPaths = reject (== '/'), folderPaths

      for path in folderPaths
        depth = depthOf path
        folderPath =
            value: path
            displayPath: path # folderDisplayPath folderPath
            included: false
            depth: depth
            open: false
        paths.push folderPath

      sortPathsInPlace paths
      updateHideCounts paths
      $scope.paths = paths

  # Places deep paths at the end. Sorts alphabetically, at each depth.
  sortPathsInPlace = (paths) ->
    paths.sort (a, b) ->
      partsA = a.value.split '/'
      partsB = b.value.split '/'
      lenA = partsA.length
      lenB = partsB.length
      minLen = Math.min(lenA, lenB)
      for ix from 1 to minLen
        partA = partsA[ix]
        partB = partsB[ix]
        # Sort a folder before the pages in it.
        # (A folder and its index page has identical `value`s, e.g. `/folder/`.)
        if ix + 1 == lenA and lenA == lenB
          return -1 if isFolder(a) and isPage(b)
          return 1 if isFolder(b) and isPage(a)
        # Sort pages before folders
        return -1 if ix + 1 == lenA and lenA < lenB
        return 1 if ix + 1 == lenB and lenB < lenA
        # Sort alphabetically
        return -1 if partA < partB
        return 1 if partB < partA
      return 0

  $scope.updateSelectedPaths = ->
    trees = []
    folders = []<commit_msg>Admin SPA: Don't recreate $scope.paths when adding page.<commit_after># Copyright (c) 2012 <NAME>. All rights reserved

import prelude


AdminModule = angular.module('AdminModule', [])



AdminModule.filter 'filterProp', ->
  (inputs, propName, textToMatch) ->
    [i for i in inputs when i[propName].search(textToMatch) >= 0]



AdminModule.factory 'AdminService', ['$http', ($http) ->

  pagesById = {}
  api = {}
  selectedPathsListeners = []

  api.selectPaths = (treesFoldersPageIds) ->
    for listener in selectedPathsListeners
      listener(treesFoldersPageIds)

  api.onPathSelectionChange = (listener) ->
    selectedPathsListeners.push listener

  api.getPageById = (pageId) ->
    if pagesById == {} then api.listAllPages -> 'noop'
    pagesById[pageId]

  api.listAllPages = (onSuccess) ->
    $http.get('/?list-pages.json&in-tree').success (data) ->
      # Angular has already parsed the JSON.
      for page in data.pages
        pagesById[page.id] = page
      onSuccess(data)

  api.listActions = (treesFoldersPageIds, onSuccess) ->
    treesStr   = treesFoldersPageIds.trees?.join(',') || ''
    foldersStr = treesFoldersPageIds.folders?.join(',') || ''
    pageIdsStr = treesFoldersPageIds.pageIds?.join(',') || ''
    $http.get("/?list-actions.json" +
        "&in-trees=#treesStr" +
        "&in-folders=#foldersStr" +
        "&for-pages=#pageIdsStr").success (data) ->
      onSuccess data

  actionsToJsonObjs = (actions) ->
    toJsonObj = (action) -> { pageId: action.pageId, actionId: action.id }
    map toJsonObj, actions

  api.approve = (actions, onSuccess) ->
    $http.post '/-/approve', actionsToJsonObjs(actions)
        .success -> onSuccess!

  api.reject = (actions, onSuccess) ->
    $http.post '/-/reject', actionsToJsonObjs(actions)
        .success -> onSuccess!

  api.delete = (actions, onSuccess) ->
    onSuccess! # for now

  api.createPage = (folder, callback) ->
    $http.post(folder + '?create-page',
        'page-title': 'Title'
        'page-slug': 'title'
        'show-id': true).success (data) ->
          callback data.newPage

  api

  ]



@PathsCtrl = ['$scope', 'AdminService', ($scope, adminService) ->

  /**
   * Creates a new page and opens it in a new browser tab.
   */
  $scope.createPage = ->
    # Open new tab directly, in direct response to the user-initiated event,
    # or the browser's pop-up blocker tends to blocks it.
    newBrowserPage = window.open 'about:blank', '_blank'
    now = new Date!
    folder = '/' +
        padNumberToLength2(now.getFullYear!) + '/' +
        padNumberToLength2(now.getMonth!) + '/' +
        padNumberToLength2(now.getDate!) + '/'
    adminService.createPage folder, (newPage) ->
      newBrowserPage.location = newPage.path
      newPage.mark = 'New'
      listOneMorePage newPage

  isPage = (path) -> path.pageId?
  isFolder = (path) -> !isPage(path)
  depthOf = (path) ->
    matches = path.match(//(/[^/]*)//g)
    matches?.length || 0

  $scope.paths = []
  $scope.isPage = isPage
  $scope.isFolder = isFolder
  $scope.isFolderOrPageClass = (path) ->
    if isPage(path) then 'is-page' else 'is-folder'

  loadAndListPages = ->
    adminService.listAllPages (data) ->
      listMorePagesDeriveFolders data.pages

  listMorePagesDeriveFolders = (morePages) ->
      folderPathsDupl = []
      paths = []

      for page in morePages
        $scope.paths.push makePageListItem(page)
        folderPathsDupl.push page.folder

      folderPaths = unique folderPathsDupl
      folderPaths = reject (== '/'), folderPaths

      for path in folderPaths
        # COULD skip `path` if $scope.paths already contains that folder.
        depth = depthOf path
        folderPath =
            value: path
            displayPath: path # folderDisplayPath folderPath
            included: false
            depth: depth
            open: false
        $scope.paths.push folderPath

      sortPathsInPlace $scope.paths
      updateHideCounts $scope.paths


  listOneMorePage = (page) ->
    $scope.paths.push makePageListItem(page)
    sortPathsInPlace $scope.paths
    updateHideCounts $scope.paths

  makePageListItem = (page) ->
    depth = depthOf page.path
    return
        pageId: page.id
        value: page.path
        displayPath: page.path
        title: page.title
        authors: page.authors
        included: false
        depth: depth
        open: false
        mark: page.mark

  # Places deep paths at the end. Sorts alphabetically, at each depth.
  sortPathsInPlace = (paths) ->
    paths.sort (a, b) ->
      partsA = a.value.split '/'
      partsB = b.value.split '/'
      lenA = partsA.length
      lenB = partsB.length
      minLen = Math.min(lenA, lenB)
      for ix from 1 to minLen
        partA = partsA[ix]
        partB = partsB[ix]
        # Sort a folder before the pages in it.
        # (A folder and its index page has identical `value`s, e.g. `/folder/`.)
        if ix + 1 == lenA and lenA == lenB
          return -1 if isFolder(a) and isPage(b)
          return 1 if isFolder(b) and isPage(a)
        # Sort pages before folders
        return -1 if ix + 1 == lenA and lenA < lenB
        return 1 if ix + 1 == lenB and lenB < lenA
        # Sort alphabetically
        return -1 if partA < partB
        return 1 if partB < partA
      return 0

  $scope.updateSelectedPaths = ->
    trees = []
    folders = []
{'fraction_non_alphanumeric': 0.1240910378694872, 'fraction_numerical': 0.0037775049579752574, 'mean_word_length': 2.4161290322580644, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5504517', 'n_tokens_mistral': 3411, 'n_tokens_neox': 3275, 'n_words': 839}