UNCLASSIFIED - NO CUI

Skip to content
Snippets Groups Projects
MissionAppProjects.vue 5.61 KiB
Newer Older
<template>
  <v-form v-model="valid">
    <v-chip-group class="px-xl-8 px-lg-8" column>
      <v-tooltip
        v-for="(project, index) in projects"
        :key="index"
        bottom
        nudge-left
      >
        <template v-slot:activator="{ on, attrs }">
          <v-chip
            class="ma-4"
            close
            color="primary"
            label
            v-bind="attrs"
            v-on="on"
            outlined
            @click="setProjectToEdit(index)"
            @click:close="deleteProject(index)"
          >
            {{ project.projectName }}
          </v-chip>
        </template>
        <pre class="projectTooltip">{{ JSON.stringify(project, null, 2) }}</pre>
      </v-tooltip>
    </v-chip-group>
    <v-row class="">
      <v-col
        cols="12"
        xl="6"
        lg="6"
        class="d-flex flex-column px-xl-16 px-lg-16"
            class="
              text-xl-left text-lg-left
              ml-xl-0 ml-lg-0
              pl-lg-0 pl-lg-0
              mb-8
            "
          >
            Project Info
          </h4>
          <v-text-field
            class="mb-8"
            label="Project Name"
            v-model="project.projectName"
            hint="* Required, Unique"
            persistent-hint
            required
            :rules="[inputRules.required, unique]"
          />
          <v-text-field
            label="Bootstrap Repo Language"
            v-model="project.bootstrapWithSourceCodeRepo.language"
            hint="* optional, ie: java, react, ..."
            persistent-hint
          />
        </div>
      </v-col>
      <v-col
        cols="12"
        xl="6"
        lg="6"
        class="d-flex flex-column px-xl-16 px-lg-16"
      >
          <v-expansion-panel>
            <v-expansion-panel-header
              ><h4 class="text-left ml-0 pl-lg-0">
                Advanced Settings
              </h4></v-expansion-panel-header
            >
            <v-expansion-panel-content>
              <div class="my-lg-4 my-8">
                <MissionAppCiVariables :ciVariables="project.ciVariables" />
              </div>
              <v-text-field
                class="my-8"
                label="Port"
                :disabled="!bootstrapWithManifestRepo"
                v-model="project.port"
                hint="* Required"
                type="number"
                persistent-hint
                :rules="[
                  inputRules.required,
                  (v) => inputRules.numberGreaterThanMax(v, 65535),
                  (v) => inputRules.numberLessThanMin(v, 0),
                ]"
              />
              <MissionAppFortifyConfig
                :fortifyConfiguration="project.fortifyConfiguration"
              />
              <v-checkbox
                label="Add twistlock configuration."
                v-model="project.twistlockConfiguration"
            </v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-col>
    </v-row>
    <v-col
      cols="12"
      xl="6"
      lg="6"
      class="d-flex flex-column pb-0 pb-lg-3 px-lg-12"
      <v-btn
        :disabled="!valid"
        color="primary"
        type="button"
        class="mb-16 mr-lg-auto mr-0 my-lg-0 my-16"
        @click="handleClick"
        >{{ projectButtonText }}</v-btn
      >
  </v-form>
</template>
<script>
import MissionAppCiVariables from "@/components/MissionAppCiVariables";
import MissionAppFortifyConfig from "@/components/MissionAppFortifyConfig";
import inputRules from "@/utils/inputRules";

const createDefaultProject = () => ({
  ciVariables: [],
  bootstrapWithSourceCodeRepo: {},
});
export default {
  name: "MissionAppProjects",
  components: {
    MissionAppCiVariables,
    MissionAppFortifyConfig,
  },
  props: {
    bootstrapWithManifestRepo: {
      type: Boolean,
      required: true,
    },
    projects: {
      type: Array,
      required: true,
    },
  },
  data: () => ({
    inputRules,
    project: createDefaultProject(),
    selectedProjectIndex: undefined,
    valid: false,
  }),
  methods: {
    handleClick() {
      this.isEditing ? this.updateProject() : this.addProject();
    },
    resetProject() {
      this.project = createDefaultProject();
    },
    stopEditing() {
      this.selectedProjectIndex = undefined;
      this.resetProject();
    },
    addProject() {
      this.projects.push(this.project);
      this.resetProject();
    },
    updateProject() {
      this.projects[this.selectedProjectIndex] = this.project;
      this.stopEditing();
    },
    setProjectToEdit(index) {
      if (this.selectedProjectIndex === index) {
        this.stopEditing();
      } else {
        this.selectedProjectIndex = index;
        this.project = { ...this.projects[index] };
      }
    },
    deleteProject(index) {
      this.projects.splice(index, 1);
      if (this.selectedProjectIndex === index) {
        this.stopEditing();
      }
    },
    unique(v) {
      const projectIndex = this.projects.findIndex((p) => p.projectName === v);
      return projectIndex < 0 || projectIndex === this.selectedProjectIndex;
    },
  },
  computed: {
    isEditing() {
      return this.selectedProjectIndex !== undefined;
    },
    projectButtonText() {
      return this.isEditing ? "Update Project" : "Add Project";
    },
  },
  watch: {
    projects() {
      this.$emit("input", this.projects);
    },
  },
};
</script>
<style lang="scss" scoped>
.projectTooltip {
  text-align: left;
}
</style>