<commit_before>module Main exposing (..)

import Date
import Dict exposing (Dict)
import Html exposing (Html, h1, h2, div, pre, text, a, span, i)
import Html.Lazy
import Html.Events exposing (onClick)
import Html.Attributes exposing (class, classList, href, style)
import Html.App as Html
import Http
import ParseInt
import Regex exposing (Regex)
import Set exposing (Set)
import String
import Task exposing (Task)
import Time exposing (Time)

import GitHub
import Tracker

type alias Config =
  { githubToken : String
  , githubOrganization : String
  , trackerToken : String
  , trackerProject : Int
  , tracksuitUser : String
  }

type alias Model =
  { config : Config
  , error : Maybe String

  , repositories : List GitHub.Repo

  , backlog : Maybe (List Tracker.Iteration)
  , stories : Maybe (List Tracker.Story)
  , members : Maybe (List GitHub.User)

  , issues : List GitHub.Issue
  , missingIssues : Set Int

  , topicIterations : List Iteration

  , unscheduled : List Topic
  , engaged : List UntriagedIssue
  , pending : List UntriagedIssue
  , orphaned : List OrphanedStory

  , themWaiting : Set Int -- GitHub issue IDs
  }

type alias Topic =
  { stories : List Tracker.Story
  , issues : List GitHub.Issue
  }

type alias UntriagedIssue =
  { story : Tracker.Story
  , issue : GitHub.Issue
  }

type alias OrphanedStory =
  { story : Tracker.Story
  , issue : Maybe GitHub.Issue
  }

type alias Iteration =
  { number : Int
  , topics : List Topic
  }

main : Program Config
main =
  Html.programWithFlags
    { init = init
    , update = update
    , view = Html.Lazy.lazy view
    , subscriptions = always Sub.none
    }

type Msg
  = Noop
  | BacklogFetched (List Tracker.Iteration)
  | StoriesFetched (List Tracker.Story)
  | MembersFetched (List GitHub.User)
  | RepositoriesFetched (List GitHub.Repo)
  | IssuesFetched GitHub.Repo (List GitHub.Issue)
  | OrphanedStoryIssueFetched Tracker.Story GitHub.Issue
  | OrphanedStoryIssueMissing Tracker.Story
  | IssueCommentsFetched GitHub.Issue (List GitHub.Comment)
  | Engage UntriagedIssue
  | Engaged UntriagedIssue Tracker.Story
  | Disengage UntriagedIssue
  | Disengaged UntriagedIssue Tracker.Story
  | DeleteOrphanedStory OrphanedStory
  | OrphanedStoryDeleted OrphanedStory
  | Error String

init : Config -> (Model, Cmd Msg)
init config =
  ( { config = config
    , error = Nothing

    , repositories = []

    , backlog = Nothing
    , stories = Nothing
    , members = Nothing

    , issues = []
    , missingIssues = Set.empty

    , topicIterations = []
    , unscheduled = []
    , engaged = []
    , pending = []
    , orphaned = []

    , themWaiting = Set.empty
    }
  , fetchBacklogAndStoriesAndIssues config
  )

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Noop ->
      (model, Cmd.none)

    BacklogFetched backlog ->
      processIfReady { model | backlog = Just backlog }

    StoriesFetched stories ->
      processIfReady { model | stories = Just stories }

    MembersFetched members ->
      processIfReady { model | members = Just members }

    RepositoriesFetched repos ->
      ( { model
        | repositories = repos
        , missingIssues = Set.fromList (List.map .id repos)
        }
      , Cmd.batch <|
          List.map (fetchIssues model.config) repos
      )

    IssuesFetched repo issues ->
      processIfReady
        { model
        | issues = issues ++ model.issues
        , missingIssues = Set.remove repo.id model.missingIssues
        }

    OrphanedStoryIssueFetched story issue ->
      ({ model | orphaned = { story = story, issue = Just issue } :: model.orphaned }, Cmd.none)

    OrphanedStoryIssueMissing story ->
      ({ model | orphaned = { story = story, issue = Nothing } :: model.orphaned }, Cmd.none)

    IssueCommentsFetched issue comments ->
      if lastActivityIsUs model comments then
        (model, Cmd.none)
      else
        ({ model | themWaiting = Set.insert issue.id model.themWaiting }, Cmd.none)

    Engage issue ->
      (model, engage model.config issue)

    Engaged issue startedStory ->
      let
        removeNoLongerPending =
          List.filter ((/=) issue.issue.id << .id << .issue)

        startedIssue =
          { issue | story = startedStory }
      in
        ( { model | pending = removeNoLongerPending model.pending }
        , checkEngagement model.config issue.issue
        )

    Disengage issue ->
      (model, disengage model.config issue)

    Disengaged issue _ ->
      let
        removeEngaged =
          List.filter ((/=) issue.issue.id << .id << .issue)
      in
        ( { model | engaged = removeEngaged model.engaged }
        , Cmd.none
        )

    DeleteOrphanedStory orphan ->
      (model, deleteStory model.config orphan)

    OrphanedStoryDeleted orphan ->
      let
        removeDeleted =
          List.filter ((/=) orphan.story.id << .id << .story)
      in
        ( { model
          | orphaned = removeDeleted model.orphaned
          }
        , Cmd.none
        )<commit_msg>fix: when engaging story, add to engaged section<commit_after>module Main exposing (..)

import Date
import Dict exposing (Dict)
import Html exposing (Html, h1, h2, div, pre, text, a, span, i)
import Html.Lazy
import Html.Events exposing (onClick)
import Html.Attributes exposing (class, classList, href, style)
import Html.App as Html
import Http
import ParseInt
import Regex exposing (Regex)
import Set exposing (Set)
import String
import Task exposing (Task)
import Time exposing (Time)

import GitHub
import Tracker

type alias Config =
  { githubToken : String
  , githubOrganization : String
  , trackerToken : String
  , trackerProject : Int
  , tracksuitUser : String
  }

type alias Model =
  { config : Config
  , error : Maybe String

  , repositories : List GitHub.Repo

  , backlog : Maybe (List Tracker.Iteration)
  , stories : Maybe (List Tracker.Story)
  , members : Maybe (List GitHub.User)

  , issues : List GitHub.Issue
  , missingIssues : Set Int

  , topicIterations : List Iteration

  , unscheduled : List Topic
  , engaged : List UntriagedIssue
  , pending : List UntriagedIssue
  , orphaned : List OrphanedStory

  , themWaiting : Set Int -- GitHub issue IDs
  }

type alias Topic =
  { stories : List Tracker.Story
  , issues : List GitHub.Issue
  }

type alias UntriagedIssue =
  { story : Tracker.Story
  , issue : GitHub.Issue
  }

type alias OrphanedStory =
  { story : Tracker.Story
  , issue : Maybe GitHub.Issue
  }

type alias Iteration =
  { number : Int
  , topics : List Topic
  }

main : Program Config
main =
  Html.programWithFlags
    { init = init
    , update = update
    , view = Html.Lazy.lazy view
    , subscriptions = always Sub.none
    }

type Msg
  = Noop
  | BacklogFetched (List Tracker.Iteration)
  | StoriesFetched (List Tracker.Story)
  | MembersFetched (List GitHub.User)
  | RepositoriesFetched (List GitHub.Repo)
  | IssuesFetched GitHub.Repo (List GitHub.Issue)
  | OrphanedStoryIssueFetched Tracker.Story GitHub.Issue
  | OrphanedStoryIssueMissing Tracker.Story
  | IssueCommentsFetched GitHub.Issue (List GitHub.Comment)
  | Engage UntriagedIssue
  | Engaged UntriagedIssue Tracker.Story
  | Disengage UntriagedIssue
  | Disengaged UntriagedIssue Tracker.Story
  | DeleteOrphanedStory OrphanedStory
  | OrphanedStoryDeleted OrphanedStory
  | Error String

init : Config -> (Model, Cmd Msg)
init config =
  ( { config = config
    , error = Nothing

    , repositories = []

    , backlog = Nothing
    , stories = Nothing
    , members = Nothing

    , issues = []
    , missingIssues = Set.empty

    , topicIterations = []
    , unscheduled = []
    , engaged = []
    , pending = []
    , orphaned = []

    , themWaiting = Set.empty
    }
  , fetchBacklogAndStoriesAndIssues config
  )

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Noop ->
      (model, Cmd.none)

    BacklogFetched backlog ->
      processIfReady { model | backlog = Just backlog }

    StoriesFetched stories ->
      processIfReady { model | stories = Just stories }

    MembersFetched members ->
      processIfReady { model | members = Just members }

    RepositoriesFetched repos ->
      ( { model
        | repositories = repos
        , missingIssues = Set.fromList (List.map .id repos)
        }
      , Cmd.batch <|
          List.map (fetchIssues model.config) repos
      )

    IssuesFetched repo issues ->
      processIfReady
        { model
        | issues = issues ++ model.issues
        , missingIssues = Set.remove repo.id model.missingIssues
        }

    OrphanedStoryIssueFetched story issue ->
      ({ model | orphaned = { story = story, issue = Just issue } :: model.orphaned }, Cmd.none)

    OrphanedStoryIssueMissing story ->
      ({ model | orphaned = { story = story, issue = Nothing } :: model.orphaned }, Cmd.none)

    IssueCommentsFetched issue comments ->
      if lastActivityIsUs model comments then
        (model, Cmd.none)
      else
        ({ model | themWaiting = Set.insert issue.id model.themWaiting }, Cmd.none)

    Engage issue ->
      (model, engage model.config issue)

    Engaged issue startedStory ->
      let
        removeNoLongerPending =
          List.filter ((/=) issue.issue.id << .id << .issue)

        startedIssue =
          { issue | story = startedStory }
      in
        ( { model
          | pending = removeNoLongerPending model.pending
          , engaged = startedIssue :: model.engaged
          }
        , checkEngagement model.config issue.issue
        )

    Disengage issue ->
      (model, disengage model.config issue)

    Disengaged issue _ ->
      let
        removeEngaged =
          List.filter ((/=) issue.issue.id << .id << .issue)
      in
        ( { model | engaged = removeEngaged model.engaged }
        , Cmd.none
        )

    DeleteOrphanedStory orphan ->
      (model, deleteStory model.config orphan)

    OrphanedStoryDeleted orphan ->
      let
        removeDeleted =
          List.filter ((/=) orphan.story.id << .id << .story)
      in
        ( { model
          | orphaned = removeDeleted model.orphaned
          }
        , Cmd.none
        )
{'fraction_non_alphanumeric': 0.09164287823604686, 'fraction_numerical': 0.0003937395412934344, 'mean_word_length': 2.5216637781629117, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 39, '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': '1245620', 'n_tokens_mistral': 3291, 'n_tokens_neox': 3052, 'n_words': 844}