<commit_before>import Controller from "@ember/controller";
import { or, reads, uniqBy } from "@ember/object/computed";
import { inject as service } from "@ember/service";
import { task } from "ember-concurrency";
import { all } from "rsvp";
import TaskValidations from "timed/validations/task";

export default Controller.extend({
  TaskValidations,

  session: service(),
  notify: service(),
  user: reads("session.data.user"),
  projects: reads("fetchProjectsOfUser.lastSuccessful.value"),
  filteredProjects: reads("filterProjects.lastSuccessful.value"),
  tasks: reads("fetchTasksOfProject.lastSuccessful.value"),
  customers: uniqBy("fetchCustomersOfProject.lastSuccessful.value", "id"),
  loading: or(
    "fetchTasksOfProject.isRunning",
    "fetchCustomersOfProject.isRunning"
  ),

  fetchProjectsOfUser: task(function*() {
    try {
      let projects;
      if (this.get("user.isSuperuser")) {
        projects = yield this.store.findAll("project");
      } else {
        projects = yield this.store.query("project", {
          has_reviewer: this.get("user.id")
        });
      }

      this.fetchCustomersOfProject.perform(projects);
      return projects;
    } catch (error) {
      this.notify.error("Error while fetching projects");
    }
  }),

  fetchCustomersOfProject: task(function*(projects) {
    return yield all(
      projects.map(async project => {
        return await project.get("customer");
      })
    );
  }),

  filterProjects: task(function*() {
    return yield this.get("projects").filter(
      project => project.get("customer.id") === this.get("selectedCustomer.id")
    );
  }),

  fetchTasksOfProject: task(function*() {
    try {
      return yield this.store.query("task", {
        project: this.get("selectedProject.id")
      });
    } catch (error) {
      this.notify.error("Error while fetching tasks");
    }
  }).drop(),

  saveTask: task(function*(changeset) {
    try {
      yield changeset.save();

      this.notify.success("Task was saved");
    } catch (error) {
      /* istanbul ignore next */
      this.notify.error("Error while saving task");
    }

    this.fetchTasksOfProject.perform(this.get("selectedProject"));
  }).drop(),

  createTask: task(function*() {
    this.set(
      "selectedTask",
      yield this.store.createRecord("task", {
        project: this.get("selectedProject")
      })
    );
  }).drop(),

  actions: {
    handleCustomerChange(customer) {
      this.set("selectedCustomer", customer);
      this.set("selectedProject", null);
      this.set("selectedTask", null);

      this.filterProjects.perform();
    },

    handleProjectChange(project) {
      this.set("selectedProject", project);
      this.set("selectedTask", null);

      if (this.get("selectedProject") !== null) {
        this.fetchTasksOfProject.perform();
      }
    }
  }
});<commit_msg>fix: include customers when fetching projects<commit_after>import Controller from "@ember/controller";
import { computed } from "@ember/object";
import { reads } from "@ember/object/computed";
import { inject as service } from "@ember/service";
import { task } from "ember-concurrency";
import TaskValidations from "timed/validations/task";

export default Controller.extend({
  TaskValidations,

  session: service(),
  notify: service(),
  user: reads("session.data.user"),
  projects: reads("fetchProjectsByUser.lastSuccessful.value"),
  filteredProjects: reads("filterProjects.lastSuccessful.value"),
  tasks: reads("fetchTasksByProject.lastSuccessful.value"),
  loading: reads("fetchTasksByProject.isRunning"),

  customers: computed("projects", function() {
    return (
      this.get("projects")
        ?.map(project => project.get("customer"))
        .uniqBy("id")
        .sortBy("name") ?? []
    );
  }),

  fetchProjectsByUser: task(function*() {
    try {
      let projects;
      if (this.get("user.isSuperuser")) {
        projects = yield this.store.findAll("project");
      } else {
        projects = yield this.store.query("project", {
          has_manager: this.get("user.id"),
          include: "customer"
        });
      }

      return projects.sortBy("name");
    } catch (error) {
      this.notify.error("Error while fetching projects");
    }
  }),

  filterProjects: task(function*() {
    return yield this.get("projects").filter(
      project => project.get("customer.id") === this.get("selectedCustomer.id")
    );
  }),

  fetchTasksByProject: task(function*() {
    try {
      return yield this.store.query("task", {
        project: this.get("selectedProject.id")
      });
    } catch (error) {
      this.notify.error("Error while fetching tasks");
    }
  }).drop(),

  saveTask: task(function*(changeset) {
    try {
      yield changeset.save();

      this.notify.success("Task was saved");
    } catch (error) {
      /* istanbul ignore next */
      this.notify.error("Error while saving task");
    }

    this.fetchTasksByProject.perform(this.get("selectedProject"));
  }).drop(),

  createTask: task(function*() {
    this.set(
      "selectedTask",
      yield this.store.createRecord("task", {
        project: this.get("selectedProject")
      })
    );
  }).drop(),

  actions: {
    handleCustomerChange(customer) {
      this.set("selectedCustomer", customer);
      this.set("selectedProject", null);
      this.set("selectedTask", null);

      this.filterProjects.perform();
    },

    handleProjectChange(project) {
      this.set("selectedProject", project);
      this.set("selectedTask", null);

      if (this.get("selectedProject") !== null) {
        this.fetchTasksByProject.perform();
      }
    }
  }
});
{'fraction_non_alphanumeric': 0.1548421426037602, 'fraction_numerical': 0.0, 'mean_word_length': 3.180133432171979, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '1973382', 'n_tokens_mistral': 1655, 'n_tokens_neox': 1627, 'n_words': 308}