* Add sorting to ACLs roles with comparator
* Add acls/roles sorting test
* Add navigation feature test to roles
* Update onchange value target for sorting roles
* Add sorting to ACLs tokens with tests
* Create token comparator and implement in template
* Upgrade @hashicorp/consul-api-double to 3.1.6
* Add navigation test to acls tokens
* Add sorting to Intentions with tests
* Skip Intentions url back test
* Create comparator for intention and implement in template
* Add a intentions navigation feature test
* Add components for KV form, KV list and Session form
* Pass through a @label attribute for a human label + don't require error
* Ignore transition aborted errors for if you are re-transitioning
* Make old confirmation dialog more ember-like and tagless
* Make sure data-source and data-sink supports KV and sessions
* Use new components and delete all the things
* Fix up tests
* Make list component tagless
* Add component pageobject and fixup tests from that
* Add eslint warning back in
* Add uri identifiers to all data source things and make them the same
1. Add uri identitifer to data-source service
2. Make <EventSource /> and <DataSource /> as close as possible
3. Add extra `.closed` method to get a list of inactive/closed/closing
data-sources from elsewhere
* Make the connections cleanup the least worst connection when required
* Pass the uri/request id through all the things
* Better user erroring
* Make event sources close on error
* Allow <DataLoader /> data slot to be configurable
* Allow the <DataWriter /> removed state to be configurable
* Don't error if meta is undefined
* Stitch together all the repositories into the data-source/sink
* Use data.source over repositories
* Add missing <EventSource /> components
* Fix up the views/templates
* Disable all the old route based blocking query things
* We still need the repo for the mixin for the moment
* Don't default to default, default != ''
* ui: Reduce discovery-chain log spam
Currently the only way that the UI can know whether connect is enabled
or not is whether we get 500 errors from certain endpoints.
One of these endpoints we already use, so aswell as recovering from a
500 error, we also remember that connect is disabled for the rest of the
page 'session' (so until the page is refreshed), and make no further
http requests to the endpoint for that specific datacenter.
This means that log spam is reduced to only 1 log per page refresh/dc
instead of 1 log per service navigation.
Longer term we'll need some way to dynamically discover whether connect
is enabled per datacenter without relying on something that will add
error logs to consul.
* Remove gateway endpoint adapter, model, and serializer and tests
* Update service tests to handle gateway-services-nodes
* Upgrade consul-api-double to 2.15.2
* Add a fairly temporary shouldReconcile method
Co-authored-by: John Cowen <jcowen@hashicorp.com>
* ui: Styling fixes (#7885)
* Move cellHeight to ListCollection js file
* Fix composite row border-top-color onHover state
* Add empty health check icon to CompositeRow styling
* ui: Slightly refactor %composite-rows and reuse ConsulServiceList component (#7886)
* ui: Move individual component types into a single %composite-list plus
1. Removes all out separate CSS components (that match HTML components)
to favour not having those separate for the moemnt at least
2. Reuses <ConsulServiceList /> component for Terminating Gateways >
Linked Services
* ui: Tweak breadcrumb spacing for '/' separator
* Fix up the tests i.e. services per tab so we can call them all services
* ui: Misc discovery chain fixes (#7892)
1. Look for a default splitter before looking for a default resolver in
order to route to.
2. Delay adding svg listeners until afterRender (fixes split tooltip)
3. Make router id's consistent for highlighting default routers in when
clicking the graph
* ui: If an error occurs on the server, surface it in the notification (#7893)
* ui: Delete old unused CSS (#7909)
This commit deletes CSS that we no longer use and we definitely will not
ever use.
We also dedup all of our imports here as it turns out SASS doesn't
dedupe imports. Strangely this increases out CSS weight by ~1kb instead
of reducing but we'd rather keep things deduped as that was the
intention
* ui: Redesign - Exposed Paths (#7912)
* Add new exposed paths icons to codebase
* Redesign Exposed Paths and create copy-button hover on Composite Row
* Refactor FeedbackDialog and CopyButton
* Change this.element to use `{{ref }}` now we don't have an element
We changed this to a tagless component with an eye to moving this to a
glimmer component, without spotting that this would also remove the
`this.element` property.
This adds an equivalent using the ref modifier.
Co-authored-by: John Cowen <jcowen@hashicorp.com>
* ui: Remove box-shadow and pointer cursor from metada list hover effect (#7914)
Co-authored-by: Kenia <19161242+kaxcode@users.noreply.github.com>
Originally we assumed all settings would be editable in the settings
page, but over time we've added thigns to localStorage that aren't user
settable settings. This means we shouldn't save all you localStorage
settings everything time only a single setting has been saved.
This change only changes the setting you've changed via the settings
page, meaning it will never update non-user-settable settings.
* Fix to bottom border not applying to the correct <li>
* Create Linked Services tab with styling and tests
* Add internal endpoint gateway-services-nodes to the codebase with tests
* Upgrade consul-api-double to version 2.15.0
* 6 new components for new login/logout flow, plus SSO support
UI Components:
1. AuthDialog: Wraps/orchestrates AuthForm and AuthProfile
2. AuthForm: Authorization form shown when logged out.
3. AuthProfile: Simple presentational component to show the users
'Profile'
4. OidcSelect: A 'select' component for selecting an OIDC provider,
dynamically uses either a single select menu or multiple buttons
depending on the amount of providers
Data Components:
1. JwtSource: Given an OIDC provider URL this component will request a
token from the provider and fire an donchange event when it has been
retrieved. Used by TokenSource.
2. TokenSource: Given a oidc provider name or a Consul SecretID,
TokenSource will use whichever method/API requests required to retrieve
Consul ACL Token, which is emitted to the onchange event handler.
Very basic README documentation included here, which is likely to be
refined somewhat.
* CSS required for new auth/SSO UI components
* Remaining app code required to tie the new auth/SSO work together
* CSS code required to help tie the auth/SSO work together
* Test code in order to get current tests passing with new auth/SSO flow
..plus extremely basics/skipped rendering tests for the new components
* Treat the secret received from the server as the truth
Previously we've always treated what the user typed as the truth, this
breaks down when using SSO as the user doesn't type anything to retrieve
a token. Therefore we change this so that we use the secret in the API
response as the truth.
* Make sure removing an dom tree from a buffer only removes its own tree
* Fix clickFirstAnchor bug
* Create Proxy Info Tab for Instance Detail Page
* Create tests for ProxyInfo and update other scenarios with Proxy data
* ui: Refactors our app-view/%app-view component (#7752)
Co-authored-by: John Cowen <johncowen@users.noreply.github.com>
* Remove Proxy link and add ExternalSource to instance detail page header
* Create HealthChecks tab with route and styling
* Fix up tests to fit redesign of Service Instances Detail page
* Make datacenter queries use query vs findAll like the rest of the app
* Make sure we have an element to pass to isInViewport
* Make sure href-mut doesn't error even if the currentRoute === null
* More post test cleanup and Safari fix (safari requires http:// URLs)
* Reverse order of datasource nspace/dc's and add a namespace source
* Rearrange routes/templates/controllers to only use HashicorpConsul once
* Add datasources and correct token namespace detection/redirection
* Remove old dc findAll adapter method
* Add more comments around the 'child route/parent controller' vars
* Create ConsulServiceInstanceList with styling and test
* Implement ConsulServiceInstanceList to Service Detail page
* Implement ConsulExternalSource to Services Show page header
* Update services/show page object
* Update the styling of CompositeRow
* Refactor ConsulServiceList component and styling
* Update ConsulExternalSource to say 'Registered via...'
* Upgrade consul-api-double to patch 2.14.1
* Fix up tests to not use Kind in service models
* Update ListCollection with clickFirstAnchor action
* Add $typo-size-450 to typography base variables
* Add model layer support for filtering intentions by service
* Add Route, Controller and template for services.show.intentions tab
We are still loading the intentions themselves in the parent Route for
the moment
* Load the intentions in in the parent route for the moment
* Temporarily add support for returning to history -1
Once we have an intention form underneath the service/intention tab this
will no longer be needed
* Add the new tab and enable blocking queries for it
* Add some further acceptance testing around intention listings
* ui: Logout button
This commit adds an easier way to logout of the UI using a logout button
Notes:
- Added a Logout button to the main navigation when you are logged in,
meaning you have easy access to a way to log out of the UI.
- Changed all wording to use 'Log in/out' vocabulary instad of 'stop
using'.
- The logout button opens a panel to show you your current ACL
token and a logout button in order to logout.
- When using legacy ACLs we don't show the current ACL token as legacy
ACLs tokens only have secret values, whereas the new ACLs use a
non-secret ID plus a secret ID (that we don't show).
- We also added a new `<EmptyState />` component to use for all our
empty states. We currently only use this for the ACLs disabled screen to
provide more outgoing links to more readind material/documentation to
help you to understand and enable ACLs.
- The `<DataSink />` component is the sibling to our `<DataSource />`
component and whilst is much simpler (as it doesn't require polling
support), its tries to use the same code patterns for consistencies
sake.
- We had a fun problem with ember-data's `store.unloadAll` here, and in
the end went with `store.init` to empty the ember-data store instead due
to timing issues.
- We've tried to use already existing patterns in the Consul UI here
such as our preexisting `feedback` service, although these are likely to
change in the future. The thinking here is to add this feature with as
little change as possible.
Overall this is a precursor to a much larger piece of work centered on
auth in the UI. We figured this was a feature complete piece of work as
it is and thought it was worthwhile to PR as a feature on its own, which
also means the larger piece of work will be a smaller scoped PR also.
* ui: Add tab navigation to the browser history/URLs
This commit changes all our tabbed UI interfaces in the catalog to use
actual URL changes rather than only updating the content in the page
using CSS.
Originally we had decided not to add tab clicks into the browser
history for a variety of reasons. As the UI has progressed these tabs
are a fairly common pattern we are using and as the UI grows and
stabilizes around certain UX patterns we've decided to make these tabs
'URL changing'.
Pros:
- Deeplinking
- Potentially smaller Route files with a more concentrated scope of the
contents of a tab rather than the entire page.
- Tab clicks now go into your history meaning backwards and forwards
buttons take you through the tabs not just the pages.
- The majority of our partials are now fully fledged templates (Octane
🎉)
Cons:
- Tab clicks now go into your history meaning backwards and forwards
buttons take you through the tabs not just the pages. (Could be good and
bad from a UX perspective)
- Many more Route and Controller files (yet as mentioned above each of these
have a more reduced scope)
- Moving around the contents of these tabs, or changing the visual names
of them means updates to the URL structure, which then should
potentially entail redirects, therefore what things that seem like
straightforwards design reorganizations are now a little more impactful.
It was getting to the point that the Pros outweight the Cons
Apart from moving some files around we made a few more tiny tweaks to
get this all working:
- Our freetext-filter component now performs the initial search rather
than this happening in the Controller (remove of the search method in
the Controllers and the new didInsertElement hook in the component)
- All of the <TabNav>'s were changed to use its alternative href
approach.
- <TabPanel>s usage was mostly removed. This is th thing I dislike the
most. I think this needs removing, but I'd also like to remove the HTML
it creates. You'll see that every new page is wrappe din the HTML for
the old <TabPanel>, this is to continue to use the same HTML structure
and id's as before to avoid making further changes to any CSS that might
use this and being able to target things during testing. We could have
also removed these here, but it would have meant a much larger changeset
and can just as easily be done at a later date.
- We made a new `tabgroup` page-object component, which is almost
identical to the previous `radiogroup` one and injected that instead
where needed during testing.
* Make sure we pick up indexed routes when nspaces are enabled
* Move session invalidation to the child (session) route
* Revert back to not using didInsertElement for updating the searching
This adds a way for the searchable to remember the last search result
instead, which changes less and stick to the previous method of
searching.
Whilst we tried to do this with the smallest amount of changes possible,
our acceptance tests for trying to submit a blank form started failing
due to usage of `destroyRecord`, its seems that the correct way to
achieve the same thing is to use `rollbackAttributes` instead. We
changed that here and the tests pass once again. Furture work related to
this will involve change the rest of the UI where we use `destroyRecord`
to achieve the same thing, to use `rollbackAttributes` instead
* Modify templates with codemods angle brackets
* ui: Fix up problem with intention filter action attribute
Co-authored-by: Kenia <19161242+kaxcode@users.noreply.github.com>
When using namespaces, the 'default' namespace is a little special in
that we wanted the option for all our URLs to stay the same when using
namespaces if you are using the default namespace, with the option of
also being able to explicitly specify `~default` as a namespace.
In other words both `ui/services/service-name` and
`ui/~default/services/service-name` show the same thing.
This means that if you switch between OSS and Enterprise, all of your
URLs stay the same, but you can still specifically link to the default
namespace itself.
Our routing configuration is duplicated in order to achieve this:
```
- :dc
- :service
- :kv
- :edit
- :nspace
- :dc
- :service
- :kv
- :edit
```
Secondly, ember routing resolves/matches routes in the order that you specify
them, unless, its seems, when using wildcard routes, like we do in the
KV area.
When not using the wildcard routes the above routing configuration
resolves/matches a `/dc-1/kv/service` to the `dc.kv.edit` route correctly
(dc:dc-1, kv:services), that route having been configured in a higher
priority than the nspace routes.
However when configured with wildcards (required in the KV area), note
the asterisk below:
```
- :dc
:service
- :kv
- *edit
- :nspace
- :dc
- :service
- :kv
- *edit
```
Given something like `/dc-1/kv/services` the router instead matches the
`nspace.dc.service` (nspace:dc-1, dc:kv, service:services) route first even
though the `dc.kv.edit` route should still match first.
Changing the `dc.kv.edit` route back to use a non-wildcard route
(:edit instead of *edit), returns the router to match the routes in the
correct order.
In order to work around this, we catch any incorrectly matched routes
(those being directed to the nspace Route but not having a `~`
character in the nspace parameter), and then recalculate the correct
route name and parameters. Lastly we use this recalculated route to
direct the user/app to the correct route.
This route recalcation requires walking up the route to gather up all of
the required route parameters, and although this feels like something
that could already exist in ember, it doesn't seem to. We had already
done a lot of this work a while ago when implementing our `href-mut`
helper. This commit therefore repurposes that work slighlty and externalizes
it outside of the helper itself into a more usable util so we can import
it where we need it. Tests have been added before refactoring it down
to make the code easier to follow.
For URL maintenance reasons we store the last visited DC in
localStorage incase you come back to a page (for example settings) that
doesn't have a dc in the URL.
A problem arises here if the last DC you tried to visit is unreachable.
The first fix here clears out the last visited DC from localStorage if
the API has errored out.
Secondly, our `href-mut` helper which mutates the current current and
replaces 'parts' in the URL rather than the whole thing functioned by
detecting the current route/URL you are on an 'mutating' that. A problem
arose here as even though you might be on the `/ui/dc-1/services` URL the
actual route is the 'error' route which does not have a URL that can be
changed properly.
The second fix here uses route.currentRoute.name over route.currentRouteName.
The latter is equal to error when an error occurs whereas the former gives you the name of the route before the error happened, which is actually what we want/the intent here.
ie. when `router.currentRouteName === 'error'` then
`router.currentRoute.name === Name Of Route Before It Errored` it seems
When connect is disabled the discovery-chain endpoint returns a 500
error status, which we previoulsy did not gracefully cope with.
This commit gracefully copes with any errors from the disco-chain
endpoint by supressing the error and hiding the Routing tab from the
Service detail page.
Acceptance test included
* Adds conditional in route to not make discovery-chain request if service kind is equal to `connect-proxy` or `mesh-gateway`
* Adds conditional in template to not show Routing tab if `chain` returns as null
* Creates a new acceptance test to test the Routing tab not being displayed for a service proxy
* Adds `tabs` to the services/show page object
* ui: Acceptance test improvements to prepare for more NS tests
* ui: Namespace acceptance testing (#7005)
* Update api-double and consul-api-double for http.body
* Adds places where we missed passing the nspace through
* Hardcode nspace CRUD to use the default nspace for policies and roles
* Alter test helpers to allow us to control nspaces from the outside
* Amends to allow tests to account for namespace, move ns from queryParam
1. We decided to move how we pass the namespace value through to the
backend when performing write actions (create, update). Previoulsy we
were using the queryParam although using the post body is the preferred
method to send the Namespace details through to the backend.
2. Other various amends to take into account testing across multiple
namespaced scenarios
* Enable nspace testing by default
* Remove last few occurances of old style http assertions
We had informally 'deprecated' our old style of http assertions that
relied on the order of http calls (even though that order was not
important for the assertion). Following on from our namespace work we
removed the majority of the old occrances of these old style assertions.
This commit removes the remaining few, and also then cleans up the
assertions/http.js file to only include the ones we are using.
This reduces our available step count further and prevents any confusion
over the usage of the old types and the new types.
* ui: Namespace CRUD acceptance tests (#7016)
* Upgrade consul-api-double
* Add all the things required for testing:
1. edit and index page objects
2. enable CONSUL_NSPACE_COUNT cookie setting
3. enable mutating HTTP response bodies based on URL
* Add acceptance test for nspace edit/delete/list and searching
* Remove empty init
* Actually make the disco chain endpoint send the nspace, note:
The backend doesn't support this as yet.
* Tweak the font size of flash-messages ever so slightly
* Make sure the nspace menu is kept up to date when creating a new one
* Move comment to the correct place
* Only refresh the namespace menu if you specifically created a nspace
* Change FIXMEs to TODOs as we are happy for these to wait until later
* Add data layer for discovery chain (model/adapter/serializer/repo)
* Add routing plus template for routing tab
* Add extra deps - consul-api-double upgrade plus ngraph for graphing
* Add discovery-chain and related components and helpers:
1. discovery-chain to orchestrate/view controller
2. route-card, splitter-card, resolver card to represent the 3 different
node types.
3. route-match helper for easy formatting of route rules
4. dom-position to figure out where things are in order to draw lines
5. svg-curve, simple wrapper around svg's <path d=""> attribute format.
6. data-structs service. This isn't super required but we are using
other data-structures provided by other third party npm modules in other
yet to be merged PRs. All of these types of things will live here for
easy access/injection/changability
7. Some additions to our css-var 'polyfill' for a couple of extra needed
rules
* Related CSS for discovery chain
1. We add a %card base component here, eventually this will go into our
base folder and %stats-card will also use it for a base component.
2. New icon for failovers
* ui: Discovery Chain Continued (#6939)
1. Add in the things we use for the animations
2 Use IntersectionObserver so we know when the tab is visible,
otherwise the dom-position helper won't work as the dom elements don't
have any display.
3. Add some base work for animations and use them a little
4. Try to detect if a resolver is a redirect. Right now this works for
datacenters and namespaces, but it can't work for services and subsets -
we are awaiting backend support for doing this properly.
5. Add a fake 'this service has no routes' route that says 'Default'
6. redirect icon
7. Add CSS.escape polyfill for Edge
Adds namespace support to the UI:
1. Namespace CRUD/management
2. Show Namespace in relevant areas (intentions, upstreams)
3. Main navigation bar improvements
4. Logic/integration to interact with a new `internal/acl/authorize` endpoint
## HTTPAdapter (#5637)
## Ember upgrade 2.18 > 3.12 (#6448)
### Proxies can no longer get away with not calling _super
This means that we can't use create anymore to define dynamic methods.
Therefore we dynamically make 2 extended Proxies on demand, and then
create from those. Therefore we can call _super in the init method of
the extended Proxies.
### We aren't allowed to reset a service anymore
We never actually need to now anyway, this is a remnant of the refactor
from browser based confirmations. We fix it as simply as possible here
but will revisit and remove the old browser confirm functionality at a
later date
### Revert classes to use ES5 style to workaround babel transp. probs
Using a mixture of ES6 classes (and hence super) and arrow functions
means that when babel transpiles the arrow functions down to ES5, a
reference to this is moved before the call to super, hence causing a js
error.
Furthermore, we the testing environment no longer lets use use
apply/call on the constructor.
These errors only manifests during testing (only in the testing
environment), the application itself runs fine with no problems without
this change.
Using ES5 style class definitions give us freedom to do all of the above
without causing any errors, so we reverted these classes back to ES5
class definitions
### Skip test that seems to have changed due to a change in RSVP timing
This test tests a usecase/area of the API that will probably never ever
be used, it was more testing out the API. We've skipped the test for now
as this doesn't affect the application itself, but left a note to come
back here later to investigate further
### Remove enumerableContentDidChange
Initial testing looks like we don't need to call this function anymore,
the function no longer exists
### Rework Changeset.isSaving to take into account new ember APIs
Setting/hanging a computedProperty of an instantiated object no longer
works. Move to setting it on the prototype/class definition instead
### Change how we detect whether something requires listening
New ember API's have changed how you can detect whether something is a
computedProperty or not. It's not immediately clear if its even possible
now. Therefore we change how we detect whether something should be
listened to or not by just looking for presence of `addEventListener`
### Potentially temporary change of ci test scripts to ensure deps exist
All our tooling scripts run through a Makefile (for people familiar with
only using those), which then call yarn scripts which can be called
independently (for people familar with only using yarn).
The Makefile targets always check to make sure all the dependencies are
installed before running anything that requires them (building, testing
etc).
The CI scripts/targets didn't follow this same route and called the yarn
scripts directly (usually CI builds a cache of the dependencies first).
For some reason this cache isn't doing what it usually does, and it
looks as though, in CI, ember isn't installed.
This commit makes the CI scripts consistently use the same method as all
of the other tooling scripts (Makefile target > Install Deps if
required > call yarn script). This should install the dependencies if
for some reason the CI cache building doesn't complete/isn't successful.
Potentially this commit may be reverted if, the root of the problem is
elsewhere, although consistency is always good, so it might be a good
idea to leave this commit as is even if we need to debug and fix things
elsewhere.
### Make test-parallel consistent with the rest of the tooling scripts
As we are here making changes for CI purposes (making test-ci
consistent), we spotted that test-parallel is also inconsistent and also
the README manual instructions won't work without `ember` installed
globally.
This commit makes everything consistent and changes the manual
instructions to use the local ember instance that gets installed via
yarn
### Re-wrangle catchable to fit with new ember 3.12 APIs
In the upgrade from ember 3.8 > 3.12 the public interfaces for
ComputedProperties have changed slightly. `meta` is no longer a public
property of ComputedProperty but of a ComputedDecoratorImpl mixin
instead.
7e4ba1096e/packages/%40ember/-internals/metal/lib/computed.ts (L725)
There seems to be no way, by just using publically available
methods, to replicate this behaviour so that we can create our own
'ComputedProperty` factory via injecting the ComputedProperty class as
we did previously.
3f333bada1/ui-v2/app/utils/computed/factory.js (L1-L18)
Instead we dynamically hang our `Catchable` `catch` method off the
instantiated ComputedProperty. In doing it like this `ComputedProperty`
has already has its `meta` method mixed in so we don't have to manually
mix it in ourselves (which doesn't seem possible)
This functionality is only used during our work in trying to ensure
our EventSource/BlockingQuery work was as 'ember-like' as possible (i.e.
using the traditional Route.model hooks and ember-like Controller
properties). Our ongoing/upcoming work on a componentized approach to
data a.k.a `<DataSource />` means we will be able to remove the majority
of the code involved here now that it seems to be under an amount of
flux in ember.
### Build bindata_assetfs.go with new UI changes
- yarn upgrade consul-api-double which includes `status/leader`
- add all the ember-data things required to call a new endpoint
- Pass the new leader variable through to the template
- use the new leader variable in the template to set a leader
- add acceptance testing to verify leaders are highlighted
- Change testing navigation/api requests to status/leader (on the node listing page, status/leader is now the last get request to
be called).
- Template whitespace commit (less indenting)
- adds a test to to assert no errors happen with an unelected leader
-Enable blocking queries by default
-Change assertion to check for the last PUT request, not just any request for session destruction from a node page.
Since we've now turned on blocking queries by default this means that a
second GET request is made after the PUT request that we are asserting
for but before the assertion itself, this meant the assertion failed. We
double checked this by turning off blocking queries for this test using
```
And settings from yaml
---
consul:client:
blocking: 0
---
```
which made the test pass again.
As moving forwards blocking queries will be on by default, we didn't
want to disable blocking queries for this test, so we now assert the
last PUT request specifically. This means we continue to assert that the
session has been destroyed but means we don't get into problems of
ordering of requests here
- Removes 'type' icons (basically the proxy icon, not the text itself)
- Add support for Mesh Gateways plus their addresses
This adds a 'Mesh Gateway' type label to service and service instance
pages, plus a new 'Addresses' tab if the service is a Mesh Gateway
showing a table of addresses for the service - plus tests
1. Includes Datacenter variable for intperolation
2. Amends text on the Settings page to reflect new keyword
3. Adds further acceptance testing around the new dashboard buttons
This PR adds a new {{template-anchor}} component. This component lets you specify a 'href template' in a handlebars like format instead of a normal string href. This template will be interpolated with the contents of a vars="" attribute.
Also contains code to add an extra UI Setting to be able to store a template to be used for this anchor in localStorage