feat: 🎸 Add discard modal for edit grants page (#3324)
This commit is contained in:
1 parent
0dac4ccf47
commit
347107c109
4 files changed
+104
-9
No files matched your search
@@ -44,7 +44,7 @@
|
|||||||
@color='secondary'
|
@color='secondary'
|
||||||
{{on 'click' @cancel}}
|
{{on 'click' @cancel}}
|
||||||
/>
|
/>
|
||||||
{{#if this.grantStringsText}}
|
{{#if this.grantStrings.length}}
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
@text={{t 'actions.export'}}
|
@text={{t 'actions.export'}}
|
||||||
@color='tertiary'
|
@color='tertiary'
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ export default class FormRoleEditGrantsComponent extends Component {
|
|||||||
exportOptionsMap = { terraform: 'terraform', nativeHCL: 'native-hcl' };
|
exportOptionsMap = { terraform: 'terraform', nativeHCL: 'native-hcl' };
|
||||||
exportOptions = Object.values(this.exportOptionsMap);
|
exportOptions = Object.values(this.exportOptionsMap);
|
||||||
|
|
||||||
@tracked grantStringsText = (this.args.model?.grant_strings ?? []).join('\n');
|
|
||||||
@tracked currentLineText = this.args.model?.grant_strings?.[0] ?? '';
|
@tracked currentLineText = this.args.model?.grant_strings?.[0] ?? '';
|
||||||
@tracked showExportOptionsFlyout = false;
|
@tracked showExportOptionsFlyout = false;
|
||||||
@tracked selectedExportOption = this.exportOptions[0];
|
@tracked selectedExportOption = this.exportOptions[0];
|
||||||
@@ -182,7 +181,11 @@ export default class FormRoleEditGrantsComponent extends Component {
|
|||||||
const line = update.state.doc.lineAt(update.state.selection.main.head);
|
const line = update.state.doc.lineAt(update.state.selection.main.head);
|
||||||
this.currentLineText = line.text;
|
this.currentLineText = line.text;
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
this.grantStringsText = update.state.doc.toString();
|
const text = update.state.doc.toString();
|
||||||
|
this.args.model.grant_strings = text
|
||||||
|
.split('\n')
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
}
|
}
|
||||||
// Trigger autocomplete when we're on an empty line
|
// Trigger autocomplete when we're on an empty line
|
||||||
if (line.text === '') {
|
if (line.text === '') {
|
||||||
@@ -200,11 +203,12 @@ export default class FormRoleEditGrantsComponent extends Component {
|
|||||||
this.#editorView?.destroy();
|
this.#editorView?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get grantStringsText() {
|
||||||
|
return this.grantStrings.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
get grantStrings() {
|
get grantStrings() {
|
||||||
return this.grantStringsText
|
return this.args.model?.grant_strings ?? [];
|
||||||
.split('\n')
|
|
||||||
.map((grantString) => grantString.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,7 +228,7 @@ export default class FormRoleEditGrantsComponent extends Component {
|
|||||||
*/
|
*/
|
||||||
get terraformFormattedExport() {
|
get terraformFormattedExport() {
|
||||||
let formatted = `grant_strings = [ \n`;
|
let formatted = `grant_strings = [ \n`;
|
||||||
this.grantStringsText.split('\n').forEach((line) => {
|
this.grantStrings.forEach((line) => {
|
||||||
formatted += ` "${line}",\n`;
|
formatted += ` "${line}",\n`;
|
||||||
});
|
});
|
||||||
formatted += `]\n`;
|
formatted += `]\n`;
|
||||||
@@ -237,7 +241,7 @@ export default class FormRoleEditGrantsComponent extends Component {
|
|||||||
*/
|
*/
|
||||||
get nativeHclFormattedExport() {
|
get nativeHclFormattedExport() {
|
||||||
let formatted = `[ \n`;
|
let formatted = `[ \n`;
|
||||||
this.grantStringsText.split('\n').forEach((line) => {
|
this.grantStrings.forEach((line) => {
|
||||||
formatted += ` "${line}",\n`;
|
formatted += ` "${line}",\n`;
|
||||||
});
|
});
|
||||||
formatted += `]\n`;
|
formatted += `]\n`;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Route from '@ember/routing/route';
|
import Route from '@ember/routing/route';
|
||||||
|
import { action } from '@ember/object';
|
||||||
import { service } from '@ember/service';
|
import { service } from '@ember/service';
|
||||||
import { dropTask } from 'ember-concurrency';
|
import { dropTask } from 'ember-concurrency';
|
||||||
import { modelMapping } from 'api/services/sqlite';
|
import { modelMapping } from 'api/services/sqlite';
|
||||||
@@ -60,4 +61,15 @@ export default class ScopesScopeRolesRoleEditGrantsRoute extends Route {
|
|||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the role model in the transition data property so that the application level hook
|
||||||
|
* can check for dirty attributes and trigger the confirm service.
|
||||||
|
* @param {object} transition
|
||||||
|
*/
|
||||||
|
@action
|
||||||
|
async willTransition(transition) {
|
||||||
|
const { role } = transition.from.attributes;
|
||||||
|
transition.data = { model: role };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -348,4 +348,83 @@ module('Acceptance | roles/edit grants', function (hooks) {
|
|||||||
|
|
||||||
assert.dom(selectors.AUTOCOMPLETE_TOOLTIP).isVisible();
|
assert.dom(selectors.AUTOCOMPLETE_TOOLTIP).isVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('can discard unsaved grant changes via dialog', async function (assert) {
|
||||||
|
setRunOptions({
|
||||||
|
rules: {
|
||||||
|
'color-contrast': {
|
||||||
|
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-06-17
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.expect(3);
|
||||||
|
const confirmService = this.owner.lookup('service:confirm');
|
||||||
|
confirmService.enabled = true;
|
||||||
|
|
||||||
|
await visit(urls.editGrants);
|
||||||
|
await waitFor(commonSelectors.CODE_EDITOR_CM);
|
||||||
|
|
||||||
|
const newGrantString = 'ids=*;type=session;actions=list';
|
||||||
|
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
|
||||||
|
const editorView = editorElement.editor;
|
||||||
|
editorView.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: editorView.state.doc.length,
|
||||||
|
insert: `\n${newGrantString}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await click(commonSelectors.HREF(urls.role));
|
||||||
|
|
||||||
|
assert.dom(commonSelectors.MODAL_WARNING).isVisible();
|
||||||
|
|
||||||
|
await click(commonSelectors.MODAL_WARNING_CONFIRM_BTN);
|
||||||
|
|
||||||
|
assert.strictEqual(currentURL(), urls.role);
|
||||||
|
console.log(this.server.schema.roles.find(instances.role.id));
|
||||||
|
assert.false(
|
||||||
|
this.server.schema.roles
|
||||||
|
.find(instances.role.id)
|
||||||
|
.grant_strings.includes(newGrantString),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can cancel discard grant changes via dialog', async function (assert) {
|
||||||
|
setRunOptions({
|
||||||
|
rules: {
|
||||||
|
'color-contrast': {
|
||||||
|
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2026-06-17
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.expect(3);
|
||||||
|
const confirmService = this.owner.lookup('service:confirm');
|
||||||
|
confirmService.enabled = true;
|
||||||
|
|
||||||
|
await visit(urls.editGrants);
|
||||||
|
await waitFor(commonSelectors.CODE_EDITOR_CM);
|
||||||
|
|
||||||
|
const newGrantString = 'ids=*;type=session;actions=list';
|
||||||
|
const editorElement = find(commonSelectors.CODE_EDITOR_CODE);
|
||||||
|
const editorView = editorElement.editor;
|
||||||
|
editorView.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: editorView.state.doc.length,
|
||||||
|
insert: `\n${newGrantString}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await click(commonSelectors.HREF(urls.role));
|
||||||
|
|
||||||
|
assert.dom(commonSelectors.MODAL_WARNING).isVisible();
|
||||||
|
|
||||||
|
await click(commonSelectors.MODAL_WARNING_CANCEL_BTN);
|
||||||
|
|
||||||
|
assert.strictEqual(currentURL(), urls.editGrants);
|
||||||
|
assert
|
||||||
|
.dom(commonSelectors.CODE_EDITOR_CONTENT)
|
||||||
|
.includesText(newGrantString);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user