<page-header title="'Create stack'" breadcrumbs="[{label:'Stacks', link:'docker.stacks'}, 'Add stack']" reload="true"> </page-header>

<div class="row">
  <div class="col-sm-12">
    <rd-widget>
      <rd-widget-body>
        <form class="form-horizontal" name="createStackForm">
          <!-- name-input -->
          <div class="form-group">
            <label for="stack_name" class="col-sm-1 control-label text-left">Name</label>
            <div class="col-sm-11">
              <input
                type="text"
                data-cy="stack-name-input"
                class="form-control"
                ng-model="formValues.Name"
                id="stack_name"
                name="stack_name"
                placeholder="e.g. mystack"
                auto-focus
                ng-pattern="STACK_NAME_VALIDATION_REGEX"
              />
              <div class="help-block" ng-show="createStackForm.stack_name.$invalid">
                <div class="small text-warning">
                  <div ng-messages="createStackForm.stack_name.$error">
                    <p ng-message="pattern">
                      <span><pr-icon icon="'alert-triangle'" class-name="'icon-sm icon-warning'"></pr-icon></span>
                      This field must consist of lower case alphanumeric characters, '_' or '-' (e.g. 'my-name', or 'abc-123').
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <!-- !name-input -->
          <div class="form-group">
            <span class="col-sm-12 text-muted small" ng-if="state.StackType === 1">
              This stack will be deployed using the equivalent of the <code>docker stack deploy</code> command.
            </span>
            <div class="col-sm-12 text-muted small" ng-if="state.StackType === 2 && composeSyntaxMaxVersion == 2">
              <div style="margin-bottom: 7px">
                This stack will be deployed using the equivalent of <code>docker compose</code>. Only Compose file format version <b>2</b> is supported at the moment.
              </div>
              <pr-icon icon="'alert-triangle'" mode="'warning'" class-name="'mr-0.5'"></pr-icon>
              Note: Due to a limitation of libcompose, the name of the stack will be standardized to remove all special characters and uppercase letters.
            </div>
            <span class="col-sm-12 text-muted small" ng-if="state.StackType === 2 && composeSyntaxMaxVersion > 2">
              This stack will be deployed using <code>docker compose</code>.
            </span>
          </div>
          <!-- build-method -->
          <div class="col-sm-12 form-section-title"> Build method </div>

          <box-selector slim="true" radio-name="'build-method'" options="buildMethods" value="state.Method" on-change="(onBuildMethodChange)" slim="true"></box-selector>

          <!-- !build-method -->

          <!-- upload -->
          <div ng-show="state.Method === 'upload'">
            <div class="col-sm-12 form-section-title"> Upload </div>
            <div class="form-group">
              <span class="col-sm-12 text-muted small"> You can upload a Compose file from your computer. </span>
              <div class="col-sm-12" ng-if="state.uploadYamlValidationError"
                ><span class="text-danger small">{{ state.uploadYamlValidationError }}</span></div
              >
            </div>
            <div class="form-group">
              <div class="col-sm-12">
                <button type="button" class="btn btn-sm btn-light" ngf-select="uploadFile($file)">
                  <pr-icon icon="'upload'"></pr-icon>
                  Select file</button
                >
                <span style="margin-left: 5px">
                  {{ formValues.StackFile.name }}
                  <pr-icon icon="'x'" mode="'danger'" ng-if="!formValues.StackFile"></pr-icon>
                </span>
              </div>
            </div>
          </div>
          <!-- !upload -->
          <git-form
            ng-if="state.Method === 'repository'"
            value="formValues"
            on-change="(onChangeFormValues)"
            is-docker-standalone="isDockerStandalone"
            is-additional-files-field-visible="true"
            is-auth-explanation-visible="true"
            is-force-pull-visible="true"
            base-webhook-url="{{ state.baseWebhookUrl }}"
            webhook-id="{{ state.webhookId }}"
            webhooks-docs="/user/docker/stacks/webhooks"
          ></git-form>

          <div ng-show="state.Method === 'template'">
            <div class="col-sm-12">
              <custom-template-selector
                new-template-path="docker.templates.custom.new"
                stack-type="state.StackType"
                on-change="(onChangeTemplateId)"
                value="state.selectedTemplateId"
              ></custom-template-selector>

              <custom-templates-variables-field
                ng-if="isTemplateVariablesEnabled && state.selectedTemplate"
                definitions="state.selectedTemplate.Variables"
                value="formValues.Variables"
                on-change="(onChangeTemplateVariables)"
              ></custom-templates-variables-field>

              <span ng-if="state.Method === 'template' && state.selectedTemplateId && state.templateLoadFailed" class="row">
                <span class="col-sm-offset-3 col-lg-offset-2 col-sm-8">
                  <p class="small vertical-center text-danger mb-5" ng-if="currentUser.isAdmin || currentUser.id === state.selectedTemplate.CreatedByUserId">
                    <pr-icon icon="'alert-triangle'" mode="'danger'" size="'md'" feather="true"></pr-icon>Custom template could not be loaded, please
                    <a ui-sref="docker.templates.custom.edit({id: state.selectedTemplateId})">click here</a> for configuration.</p
                  >
                  <p class="small vertical-center text-danger mb-5" ng-if="!(currentUser.isAdmin || currentUser.id === state.selectedTemplate.CreatedByUserId)">
                    <pr-icon icon="'alert-triangle'" mode="'danger'" size="'md'" feather="true"></pr-icon>Custom template could not be loaded, please contact your administrator.</p
                  >
                </span>
              </span>
            </div>
          </div>

          <web-editor-form
            ng-if="state.Method === 'editor' || (state.Method === 'template' && state.selectedTemplateId)"
            identifier="stack-creation-editor"
            value="formValues.StackFileContent"
            on-change="(onChangeFileContent)"
            ng-required="true"
            yml="true"
            text-tip="Define or paste the content of your docker compose file here"
            read-only="state.isEditorReadOnly"
            schema="dockerComposeSchema"
          >
            <editor-description>
              <p>
                You can get more information about Compose file format in the <a href="https://docs.docker.com/compose/compose-file/" target="_blank">official documentation</a>.
              </p>
              <p ng-if="state.editorYamlValidationError" class="text-danger">{{ state.editorYamlValidationError }}</p>
            </editor-description>
          </web-editor-form>

          <div ng-if="state.Method !== 'repository' && isAdmin && applicationState.endpoint.type !== 4">
            <div class="col-sm-12 form-section-title">
              Webhooks
              <por-switch-field
                name="EnableWebhook"
                checked="formValues.EnableWebhook"
                label-class="'col-sm-2'"
                tooltip="'Create a webhook (or callback URI) to automate the update of this stack. Sending a POST request to this callback URI (without requiring any authentication) will pull the most up-to-date version of the associated image and re-deploy this stack.'"
                label="'Create a Stack webhook'"
                on-change="(onEnableWebhookChange)"
                feature-id="'stack-webhook'"
              ></por-switch-field>
            </div>
          </div>

          <!-- environment-variables -->
          <stack-environment-variables-panel values="formValues.Env" on-change="(handleEnvVarChange)" show-alert="true"> </stack-environment-variables-panel>
          <!-- !environment-variables -->
          <por-access-control-form form-data="formValues.AccessControlData"></por-access-control-form>
          <!-- actions -->
          <div class="col-sm-12 form-section-title"> Actions </div>
          <div class="form-group">
            <div class="col-sm-12">
              <button
                type="button"
                class="btn btn-primary btn-sm !ml-0"
                ng-disabled="state.actionInProgress
              || !createStackForm.$valid
              || ((state.Method === 'editor' || state.Method === 'template') && (!formValues.StackFileContent || state.editorYamlValidationError))
              || (state.Method === 'upload' && (!formValues.StackFile || state.uploadYamlValidationError))
              || (state.Method === 'repository' && ((!formValues.RepositoryURL || !formValues.ComposeFilePathInRepository) || (formValues.RepositoryAuthentication && !formValues.RepositoryPassword)))
              || !formValues.Name"
                ng-click="deployStack()"
                button-spinner="state.actionInProgress"
                analytics-on
                analytics-category="docker"
                analytics-event="docker-stack-create"
                analytics-properties="buildAnalyticsProperties()"
              >
                <span ng-hide="state.actionInProgress">Deploy the stack</span>
                <span ng-show="state.actionInProgress">Deployment in progress...</span>
              </button>
              <span class="text-danger" ng-if="state.formValidationError" style="margin-left: 5px">{{ state.formValidationError }}</span>
            </div>
          </div>
          <!-- !actions -->
        </form>
      </rd-widget-body>
    </rd-widget>
  </div>
</div>
