open-nomad/ui/app/components/variable-form.hbs
Phil Renaud 3db9f11c37
[feat] Nomad Job Templates (#15746)
* Extend variables under the nomad path prefix to allow for job-templates (#15570)

* Extend variables under the nomad path prefix to allow for job-templates

* Add job-templates to error message hinting

* RadioCard component for Job Templates (#15582)

* chore: add

* test: component API

* ui: component template

* refact: remove  bc naming collission

* styles: remove SASS var causing conflicts

* Disallow specific variable at nomad/job-templates (#15681)

* Disallows variables at exactly nomad/job-templates

* idiomatic refactor

* Expanding nomad job init to accept a template flag (#15571)

* Adding a string flag for templates on job init

* data-down actions-up version of a custom template editor within variable

* Dont force grid on job template editor

* list-templates flag started

* Correctly slice from end of path name

* Pre-review cleanup

* Variable form acceptance test for job template editing

* Some review cleanup

* List Job templates test

* Example from template test

* Using must.assertions instead of require etc

* ui: add choose template button (#15596)

* ui: add new routes

* chore: update file directory

* ui: add choose template button

* test: button and page navigation

* refact: update var name

* ui: use `Button` component from `HDS` (#15607)

* ui: integrate  buttons

* refact: remove  helper

* ui: remove icons on non-tertiary buttons

* refact: update normalize method for key/value pairs (#15612)

* `revert`: `onCancel` for `JobDefinition`

The `onCancel` method isn't included in the component API for `JobEditor` and the primary cancel behavior exists outside of the component. With the exception of the `JobDefinition` page where we include this button in the top right of the component instead of next to the `Plan` button.

* style: increase button size

* style: keep lime green

* ui: select template (#15613)

* ui: deprecate unused component

* ui: deprecate tests

* ui: jobs.run.templates.index

* ui: update logic to handle templates

* refact: revert key/value changes

* style: padding for cards + buttons

* temp: fixtures for mirage testing

* Revert "refact: revert key/value changes"

This reverts commit 124e95d12140be38fc921f7e15243034092c4063.

* ui: guard template for unsaved job

* ui: handle reading template variable

* Revert "refact: update normalize method for key/value pairs (#15612)"

This reverts commit 6f5ffc9b610702aee7c47fbff742cc81f819ab74.

* revert: remove test fixtures

* revert: prettier problems

* refact: test doesnt need filter expression

* styling: button sizes and responsive cards

* refact: remove route guarding

* ui: update variable adapter

* refact: remove model editing behavior

* refact: model should query variables to populate editor

* ui: clear qp on exit

* refact: cleanup deprecated API

* refact: query all namespaces

* refact: deprecate action

* ui: rely on  collection

* refact: patch deprecate transition API

* refact: patch test to expect namespace qp

* styling: padding, conditionals

* ui: flashMessage on 404

* test: update for o(n+1) query

* ui: create new job template (#15744)

* refact: remove unused code

* refact: add type safety

* test: select template flow

* test: add data-test attrs

* chore: remove dead code

* test: create new job flow

* ui: add create button

* ui: create job template

* refact: no need for wildcard

* refact:  record instead of delete

* styling: spacing

* ui: add error handling and form validation to job create template (#15767)

* ui: handle server side errors

* ui: show error to prevent duplicate

* refact: conditional namespace

* ui: save as template flow (#15787)

* bug:  patches failing tests associated with `pretender` (#15812)

* refact: update assertion

* refact: test set-up

* ui: job templates manager view (#15815)

* ui: manager list view

* test: edit flow

* refact: deprecate column-helper

* ui: template edit and delete flow (#15823)

* ui: manager list view

* refact: update title

* refact: update permissions

* ui: template edit page

* bug: typo

* refact: update toast messages

* bug:  clear selections on exit (#15827)

* bug:  clear controllers on exit

* test: mirage config changes (#15828)

* refact: deprecate column-helper

* style: update z-index for HDS

* Revert "style: update z-index for HDS"

This reverts commit d3d87ceab6d083f7164941587448607838944fc1.

* refact: update delete button

* refact: edit redirect

* refact: patch reactivity issues

* styling: fixed width

* refact: override defaults

* styling: edit text causing overflow

* styling:  add inline text

Co-authored-by: Phil Renaud <phil.renaud@hashicorp.com>

* bug: edit `text` to `template`

Co-authored-by: Phil Renaud <phil.renaud@hashicorp.com>

Co-authored-by: Phil Renaud <phil.renaud@hashicorp.com>

* test:  delete flow job templates (#15896)

* refact: edit names

* bug:  set correct ref to store

* chore: trim whitespace:

* test: delete flow

* bug: reactively update view (#15904)

* Initialized default jobs (#15856)

* Initialized default jobs

* More jobs scaffolded

* Better commenting on a couple example job specs

* Adapter doing the work

* fall back to epic config

* Label format helper and custom serialization logic

* Test updates to account for a never-empty state

* Test suite uses settled and maintain RecordArray in adapter return

* Updates to hello-world and variables example jobspecs

* Parameterized job gets optional payload output

* Formatting changes for param and service discovery job templates

* Multi-group service discovery job

* Basic test for default templates (#15965)

* Basic test for default templates

* Percy snapshot for manage page

* Some late-breaking design changes

* Some copy edits to the header paragraphs for job templates (#15967)

* Added some init options for job templates (#15994)

* Async method for populating default job templates from the variable adapter

---------

Co-authored-by: Jai <41024828+ChaiWithJai@users.noreply.github.com>
2023-02-02 10:37:40 -05:00

182 lines
5.9 KiB
Handlebars

{{did-update this.onViewChange @view}}
{{did-insert this.establishKeyValues}}
<form class="new-variables" autocomplete="off" {{on "submit" this.save}}>
{{#if @model.isNew}}
{{#unless this.isJobTemplateVariable}}
<div class="related-entities related-entities-hint">
<p>Prefix your path with <code>nomad/jobs/</code> to automatically make your variable accessible to a specified job, task group, or task.<br />
Format: <code>nomad/jobs/&lt;jobname&gt;</code>, <code>nomad/jobs/&lt;jobname&gt;/&lt;groupname&gt;</code>, <code>nomad/jobs/&lt;jobname&gt;/&lt;groupname&gt;/&lt;taskname&gt;</code></p>
</div>
{{/unless}}
{{/if}}
{{#if this.hasConflict}}
<div class="notification conflict is-danger">
<h3 class="title is-4">Heads up! Your variable has a conflict.</h3>
<p>This might be because someone else tried saving in the time since you've had it open.</p>
{{#if this.conflictingVariable.modifyTime}}
<span class="tooltip" aria-label="{{format-ts this.conflictingVariable.modifyTime}}">
{{moment-from-now this.conflictingVariable.modifyTime}}
</span>
{{/if}}
{{#if this.conflictingVariable.items}}
<pre><code>{{stringify-object this.conflictingVariable.items whitespace=2}}</code></pre>
{{else}}
<p>Your ACL token limits your ability to see further details about the conflicting variable.</p>
{{/if}}
<div class="options">
<button data-test-refresh-button type="button" class="button" {{on "click" this.refresh}}>Refresh your browser</button>
<button data-test-overwrite-button type="button" class="button is-danger" {{on "click" this.saveWithOverwrite}}>Overwrite anyway</button>
</div>
</div>
{{/if}}
<div class={{if this.namespaceOptions "path-namespace"}}>
<label>
<span>
Path
</span>
<Input
@type="text"
@value={{this.path}}
placeholder="nomad/jobs/my-job/my-group/my-task"
class="input path-input {{if this.duplicatePathWarning "error"}}"
{{on "input" this.setModelPath}}
disabled={{not @model.isNew}}
{{autofocus}}
data-test-path-input
/>
{{#if this.duplicatePathWarning}}
<p class="duplicate-path-error help is-danger">
There is already a variable located at
{{this.path}}
.
<br />
Please choose a different path, or
<LinkTo
@route="variables.variable.edit"
@model={{this.duplicatePathWarning.path}}
>
edit the existing variable
</LinkTo>
.
</p>
{{/if}}
{{#if this.isJobTemplateVariable}}
<p class="help job-template-hint">
Use this variable to generate job templates with
<code>nomad job init -template={{this.jobTemplateName}}
<CopyButton
@clipboardText="nomad job init -template={{this.jobTemplateName}}"
/>
</code>
</p>
{{/if}}
</label>
<VariableForm::NamespaceFilter
@data={{hash
disabled=(not @model.isNew)
selection=this.variableNamespace
namespaceOptions=this.namespaceOptions
}}
@fns={{hash
onSelect=this.setNamespace
setNamespaceOptions=this.setNamespaceOptions
}}
/>
</div>
{{#if this.isJobTemplateVariable}}
<VariableForm::JobTemplateEditor
@keyValues={{this.keyValues}}
@updateKeyValue={{this.updateKeyValue}}
/>
{{else}}
{{#if (eq this.view "json")}}
<div
class="editor-wrapper boxed-section-body is-full-bleed
{{if this.JSONError 'error'}}"
>
<div
data-test-json-editor
{{code-mirror
content=this.JSONItems
onUpdate=this.updateCode
extraKeys=(hash Cmd-Enter=(action "save"))
}}
></div>
{{#if this.JSONError}}
<p class="help is-danger">
{{this.JSONError}}
</p>
{{/if}}
</div>
{{else}}
{{#each this.keyValues as |entry iter|}}
<div class="key-value">
<label>
<span>
Key
</span>
<Input
data-test-var-key
@type="text"
@value={{entry.key}}
class="input"
{{autofocus ignore=(eq iter 0)}}
{{on "input" (fn this.validateKey entry)}}
/>
</label>
<VariableForm::InputGroup @entry={{entry}} />
<button
class="delete-row button is-danger is-inverted"
type="button"
{{on "click" (action this.deleteRow entry)}}
>
Delete
</button>
{{#each-in entry.warnings as |k v|}}
<span class="key-value-error help is-danger">
{{v}}
</span>
{{/each-in}}
</div>
{{/each}}
{{/if}}
{{/if}}
{{#if (and this.shouldShowLinkedEntities @model.isNew)}}
<VariableForm::RelatedEntities
@new={{true}}
@job={{@model.pathLinkedEntities.job}}
@group={{@model.pathLinkedEntities.group}}
@task={{@model.pathLinkedEntities.task}}
@namespace={{this.variableNamespace}}
/>
{{/if}}
<footer>
{{#unless this.isJSONView}}
{{#unless this.isJobTemplateVariable}}
<button
class="add-more button is-info is-inverted"
type="button"
disabled={{not (and this.keyValues.lastObject.key this.keyValues.lastObject.value)}}
{{on "click" this.appendRow}}
data-test-add-kv
>
Add More
</button>
{{/unless}}
{{/unless}}
<button
disabled={{this.shouldDisableSave}}
class="button is-primary save"
type="submit"
data-test-submit-var
>
Save
{{pluralize "Variable" @this.keyValues.length}}
</button>
</footer>
</form>