mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-10-19 02:43:18 +00:00
feat: move more modals to native dialogs (#9636)
Follow up of forgejo/forgejo#8859 Move the following modals to native dialogs: - Admin notice. - Edit label. - New label. - Update email in admin's email list. Each has a E2E test to screenshot the modal and test functionality. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9636 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
parent
d0a6f93f9e
commit
8eb8f49581
13 changed files with 242 additions and 149 deletions
|
@ -75,13 +75,12 @@
|
|||
|
||||
{{template "base/paginate" .}}
|
||||
|
||||
<div class="ui g-modal-confirm modal" id="change-email-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "admin.emails.change_email_header"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p class="center">{{ctx.Locale.Tr "admin.emails.change_email_text"}}</p>
|
||||
|
||||
<dialog id="change-email-modal">
|
||||
<article>
|
||||
<header>{{ctx.Locale.Tr "admin.emails.change_email_header"}}</header>
|
||||
<div class="content">
|
||||
<p class="center">{{ctx.Locale.Tr "admin.emails.change_email_text"}}</p>
|
||||
</div>
|
||||
<form class="ui form" id="email-action-form" action="{{AppSubUrl}}/admin/emails/activate" method="post">
|
||||
{{$.CsrfTokenHtml}}
|
||||
|
||||
|
@ -99,9 +98,8 @@
|
|||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</dialog>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-email">
|
||||
|
|
|
@ -62,9 +62,14 @@
|
|||
{{template "base/paginate" .}}
|
||||
</div>
|
||||
|
||||
<div class="ui modal admin" id="detail-modal">
|
||||
<div class="header">{{ctx.Locale.Tr "admin.notices.view_detail_header"}}</div>
|
||||
<div class="content"><pre></pre></div>
|
||||
</div>
|
||||
<dialog id="detail-modal">
|
||||
<article>
|
||||
<header>{{ctx.Locale.Tr "admin.notices.view_detail_header"}}</header>
|
||||
<div class="content"><pre></pre></div>
|
||||
<div class="actions">
|
||||
<button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
|
||||
</div>
|
||||
</article>
|
||||
</dialog>
|
||||
|
||||
{{template "admin/layout_footer" .}}
|
||||
|
|
|
@ -22,7 +22,7 @@ The ".ok.button" and ".cancel.button" selectors are also used by Fomantic Modal
|
|||
{{if .ModalButtonCancelText}}{{$textNegitive = .ModalButtonCancelText}}{{end}}
|
||||
{{if .ModalButtonOkText}}{{$textPositive = .ModalButtonOkText}}{{end}}
|
||||
|
||||
<button class="ui cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button>
|
||||
<button type="button" class="ui cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button>
|
||||
<button class="ui primary ok button">{{svg "octicon-check"}} {{$textPositive}}</button>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -9,64 +9,64 @@
|
|||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
||||
<div class="ui small edit-label modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.issues.label_modify"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<form class="ui edit-label form ignore-dirty" action="{{$.Link}}/edit" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input id="label-modal-id" name="id" type="hidden">
|
||||
<div class="required field">
|
||||
<label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
|
||||
<div class="ui small input">
|
||||
<input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
|
||||
<dialog id="edit-label-modal">
|
||||
<article>
|
||||
<header>{{ctx.Locale.Tr "repo.issues.label_modify"}}</header>
|
||||
<div class="content">
|
||||
<form class="ui edit-label form ignore-dirty" action="{{$.Link}}/edit" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input id="label-modal-id" name="id" type="hidden">
|
||||
<div class="required field">
|
||||
<label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
|
||||
<div class="ui small input">
|
||||
<input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field label-exclusive-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-exclusive-input" name="exclusive" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
|
||||
<div class="field label-exclusive-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-exclusive-input" name="exclusive" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
|
||||
</div>
|
||||
<br>
|
||||
<small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
|
||||
<div class="desc tw-ml-1 tw-mt-2 tw-hidden label-exclusive-warning">
|
||||
{{svg "octicon-alert"}} {{ctx.Locale.Tr "repo.issues.label_exclusive_warning"}}
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
<br>
|
||||
<small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
|
||||
<div class="desc tw-ml-1 tw-mt-2 tw-hidden label-exclusive-warning">
|
||||
{{svg "octicon-alert"}} {{ctx.Locale.Tr "repo.issues.label_exclusive_warning"}}
|
||||
<div class="field label-is-archived-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-is-archived-input" name="is_archived" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_archive"}}</label>
|
||||
</div>
|
||||
<i class="tw-ml-1" data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}} data-tooltip-appendto="parent">
|
||||
{{svg "octicon-info"}}
|
||||
</i>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
<div class="field label-is-archived-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-is-archived-input" name="is_archived" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_archive"}}</label>
|
||||
<div class="field">
|
||||
<label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
|
||||
<div class="ui small fluid input">
|
||||
<input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
<i class="tw-ml-1" data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}>
|
||||
{{svg "octicon-info"}}
|
||||
</i>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
|
||||
<div class="ui small fluid input">
|
||||
<input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
|
||||
<div class="field color-field">
|
||||
<label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
|
||||
<div class="column js-color-picker-input">
|
||||
<input name="color" value="#70c24a"placeholder="#c320f6" required maxlength="7">
|
||||
{{template "repo/issue/label_precolors"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field color-field">
|
||||
<label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
|
||||
<div class="column js-color-picker-input">
|
||||
<input name="color" value="#70c24a"placeholder="#c320f6" required maxlength="7">
|
||||
{{template "repo/issue/label_precolors"}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ui small basic cancel button">
|
||||
{{svg "octicon-x"}}
|
||||
{{ctx.Locale.Tr "cancel"}}
|
||||
</button>
|
||||
<button class="ui primary small approve button">
|
||||
{{svg "fontawesome-save"}}
|
||||
{{ctx.Locale.Tr "save"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ui small basic cancel button">
|
||||
{{svg "octicon-x"}}
|
||||
{{ctx.Locale.Tr "cancel"}}
|
||||
</button>
|
||||
<button class="ui primary small approve button">
|
||||
{{svg "fontawesome-save"}}
|
||||
{{ctx.Locale.Tr "save"}}
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</dialog>
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
<div class="ui small new-label modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.issues.new_label"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<form class="ui new-label form ignore-dirty" action="{{$.Link}}/new" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="required field">
|
||||
<label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
|
||||
<div class="ui small input">
|
||||
<input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
|
||||
<dialog id="new-label-modal">
|
||||
<article>
|
||||
<header>{{ctx.Locale.Tr "repo.issues.new_label"}}</header>
|
||||
<div class="content">
|
||||
<form class="ui new-label form ignore-dirty" action="{{$.Link}}/new" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="required field">
|
||||
<label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
|
||||
<div class="ui small input">
|
||||
<input class="label-name-input" name="title" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_placeholder"}}" autofocus required maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field label-exclusive-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-exclusive-input" name="exclusive" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
|
||||
<div class="field label-exclusive-input-field">
|
||||
<div class="ui checkbox">
|
||||
<input class="label-exclusive-input" name="exclusive" type="checkbox">
|
||||
<label>{{ctx.Locale.Tr "repo.issues.label_exclusive"}}</label>
|
||||
</div>
|
||||
<br>
|
||||
<small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
|
||||
</div>
|
||||
<br>
|
||||
<small class="desc">{{ctx.Locale.Tr "repo.issues.label_exclusive_desc"}}</small>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
|
||||
<div class="ui small fluid input">
|
||||
<input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
|
||||
<div class="field">
|
||||
<label for="description">{{ctx.Locale.Tr "repo.issues.label_description"}}</label>
|
||||
<div class="ui small fluid input">
|
||||
<input class="label-desc-input" name="description" placeholder="{{ctx.Locale.Tr "repo.issues.new_label_desc_placeholder"}}" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field color-field">
|
||||
<label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
|
||||
<div class="js-color-picker-input column">
|
||||
<input name="color" value="#70c24a" placeholder="#c320f6" required maxlength="7">
|
||||
{{template "repo/issue/label_precolors"}}
|
||||
<div class="field color-field">
|
||||
<label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label>
|
||||
<div class="js-color-picker-input column">
|
||||
<input name="color" value="#70c24a" placeholder="#c320f6" required maxlength="7">
|
||||
{{template "repo/issue/label_precolors"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="ui cancel button">
|
||||
{{svg "octicon-x"}}
|
||||
{{ctx.Locale.Tr "cancel"}}
|
||||
</button>
|
||||
<button class="ui primary ok button">
|
||||
{{svg "octicon-check"}}
|
||||
{{ctx.Locale.Tr "repo.issues.create_label"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ui cancel button">
|
||||
{{svg "octicon-x"}}
|
||||
{{ctx.Locale.Tr "cancel"}}
|
||||
</button>
|
||||
<button class="ui primary ok button">
|
||||
{{svg "octicon-check"}}
|
||||
{{ctx.Locale.Tr "repo.issues.create_label"}}
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</dialog>
|
||||
|
|
58
tests/e2e/admin-ui.test.e2e.ts
Normal file
58
tests/e2e/admin-ui.test.e2e.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/admin/**
|
||||
// templates/admin/**
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test} from './utils_e2e.ts';
|
||||
import {screenshot} from './shared/screenshots.ts';
|
||||
|
||||
test.use({user: 'user1'});
|
||||
|
||||
test('Admin notices modal', async ({page}) => {
|
||||
const response = await page.goto('/admin/notices');
|
||||
expect(response?.status()).toBe(200);
|
||||
|
||||
await page.getByText('description1').click();
|
||||
await expect(page.locator('#detail-modal .content')).toHaveText('description1');
|
||||
await screenshot(page, page.locator('#detail-modal'));
|
||||
await page.getByText('Cancel').click();
|
||||
await expect(page.locator('#change-email-modal')).toBeHidden();
|
||||
|
||||
await page.getByText('description2').click();
|
||||
await expect(page.locator('#detail-modal .content')).toHaveText('description2');
|
||||
await screenshot(page, page.locator('#detail-modal'));
|
||||
await page.getByText('Cancel').click();
|
||||
await expect(page.locator('#change-email-modal')).toBeHidden();
|
||||
|
||||
await page.getByText('description3').click();
|
||||
await expect(page.locator('#detail-modal .content')).toHaveText('description3');
|
||||
await screenshot(page, page.locator('#detail-modal'));
|
||||
await page.getByText('Cancel').click();
|
||||
await expect(page.locator('#change-email-modal')).toBeHidden();
|
||||
});
|
||||
|
||||
test('Admin email list', async ({page}) => {
|
||||
const response = await page.goto('/admin/emails');
|
||||
expect(response?.status()).toBe(200);
|
||||
|
||||
await page.locator('[data-uid="21"]').click();
|
||||
await expect(page.locator('#change-email-modal .content')).toHaveText('Are you sure you want to update this email address?');
|
||||
await screenshot(page, page.locator('#change-email-modal .content'));
|
||||
await page.locator('#email-action-form').getByText('No').click();
|
||||
await expect(page.locator('#change-email-modal')).toBeHidden();
|
||||
|
||||
const activated = await page.locator('[data-uid="9"] .svg').evaluate((node) => node.classList.contains('octicon-check'));
|
||||
await page.locator('[data-uid="9"]').click();
|
||||
await page.getByRole('button', {name: 'Yes'}).click();
|
||||
|
||||
// Retry-proof
|
||||
if (activated) {
|
||||
await expect(page.locator('[data-uid="9"] .svg')).toHaveClass(/octicon-x/);
|
||||
} else {
|
||||
await expect(page.locator('[data-uid="9"] svg')).toHaveClass(/octicon-check/);
|
||||
}
|
||||
});
|
43
tests/e2e/repo-labels.test.e2e.ts
Normal file
43
tests/e2e/repo-labels.test.e2e.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// @watch start
|
||||
// templates/repo/issues/labels/**
|
||||
// web_src/js/features/comp/LabelEdit.js
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, dynamic_id} from './utils_e2e.ts';
|
||||
import {screenshot} from './shared/screenshots.ts';
|
||||
|
||||
test.use({user: 'user2'});
|
||||
|
||||
test('New label', async ({page}) => {
|
||||
const response = await page.goto('/user2/repo1/labels');
|
||||
expect(response?.status()).toBe(200);
|
||||
|
||||
await page.getByRole('button', {name: 'New label'}).click();
|
||||
await expect(page.locator('#new-label-modal')).toBeVisible();
|
||||
await screenshot(page, page.locator('#new-label-modal'));
|
||||
|
||||
const labelName = dynamic_id();
|
||||
await page.keyboard.type(labelName);
|
||||
await page.getByRole('button', {name: 'Create label'}).click();
|
||||
|
||||
await page.locator('.label-title').filter({hasText: labelName}).isVisible();
|
||||
});
|
||||
|
||||
test('Edit label', async ({page}) => {
|
||||
const response = await page.goto('/user2/repo1/labels');
|
||||
expect(response?.status()).toBe(200);
|
||||
|
||||
await page.getByText('Edit').first().click();
|
||||
await expect(page.locator('#edit-label-modal')).toBeVisible();
|
||||
await screenshot(page, page.locator('#edit-label-modal'));
|
||||
|
||||
const labelName = dynamic_id();
|
||||
await page.keyboard.type(labelName);
|
||||
await page.getByRole('button', {name: 'Save'}).click();
|
||||
|
||||
await page.locator('.label-title').filter({hasText: labelName}).isVisible();
|
||||
});
|
|
@ -29,8 +29,8 @@
|
|||
min-width: 100px;
|
||||
}
|
||||
|
||||
.admin code,
|
||||
.admin pre {
|
||||
:is(.admin, #detail-modal) code,
|
||||
:is(.admin, #detail-modal) pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
|
|
@ -2133,17 +2133,6 @@ details.repo-search-result summary::marker {
|
|||
padding: 1em;
|
||||
}
|
||||
|
||||
.edit-label.modal .form .column,
|
||||
.new-label.modal .form .column {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.edit-label.modal .form .buttons,
|
||||
.new-label.modal .form .buttons {
|
||||
margin-left: auto;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.stats-table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
|
|
@ -2,6 +2,7 @@ import $ from 'jquery';
|
|||
import {checkAppUrl} from '../common-global.js';
|
||||
import {hideElem, showElem, toggleElem} from '../../utils/dom.js';
|
||||
import {POST} from '../../modules/fetch.js';
|
||||
import {showModal} from '../../modules/modal.ts';
|
||||
|
||||
const {appSubUrl} = window.config;
|
||||
|
||||
|
@ -216,7 +217,7 @@ export function initAdminCommon() {
|
|||
$('.view-detail').on('click', function () {
|
||||
const description = this.closest('tr').querySelector('.notice-description').textContent;
|
||||
detailModal.querySelector('.content pre').textContent = description;
|
||||
$(detailModal).modal('show');
|
||||
showModal('detail-modal', undefined);
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import $ from 'jquery';
|
||||
import {showModal} from '../../modules/modal.ts';
|
||||
|
||||
export function initAdminEmails() {
|
||||
function linkEmailAction(e) {
|
||||
|
@ -7,7 +8,7 @@ export function initAdminEmails() {
|
|||
$('#form-email').val($this.data('email'));
|
||||
$('#form-primary').val($this.data('primary'));
|
||||
$('#form-activate').val($this.data('activate'));
|
||||
$('#change-email-modal').modal('show');
|
||||
showModal('change-email-modal', undefined);
|
||||
e.preventDefault();
|
||||
}
|
||||
$('.link-email-action').on('click', linkEmailAction);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import $ from 'jquery';
|
||||
import {showModal} from '../../modules/modal.ts';
|
||||
|
||||
function isExclusiveScopeName(name) {
|
||||
return /.*[^/]\/[^/].*/.test(name);
|
||||
|
@ -27,16 +28,14 @@ export function initCompLabelEdit(selector) {
|
|||
// Create label
|
||||
$('.new-label.button').on('click', () => {
|
||||
updateExclusiveLabelEdit('.new-label');
|
||||
$('.new-label.modal').modal({
|
||||
onApprove() {
|
||||
const form = document.querySelector('.new-label.form');
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return false;
|
||||
}
|
||||
document.querySelector('.new-label.form').requestSubmit();
|
||||
},
|
||||
}).modal('show');
|
||||
showModal('new-label-modal', () => {
|
||||
const form = document.querySelector('.new-label.form');
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return false;
|
||||
}
|
||||
document.querySelector('.new-label.form').requestSubmit();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
|
@ -64,16 +63,14 @@ export function initCompLabelEdit(selector) {
|
|||
colorInput.value = this.getAttribute('data-color');
|
||||
colorInput.dispatchEvent(new Event('input', {bubbles: true}));
|
||||
|
||||
$('.edit-label.modal').modal({
|
||||
onApprove() {
|
||||
const form = document.querySelector('.edit-label.form');
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return false;
|
||||
}
|
||||
document.querySelector('.edit-label.form').requestSubmit();
|
||||
},
|
||||
}).modal('show');
|
||||
showModal('edit-label-modal', () => {
|
||||
const form = document.querySelector('.edit-label.form');
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return false;
|
||||
}
|
||||
document.querySelector('.edit-label.form').requestSubmit();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ function attachTooltip(target, content = null) {
|
|||
hideOnClick,
|
||||
placement: target.getAttribute('data-tooltip-placement') || 'top-start',
|
||||
followCursor: target.getAttribute('data-tooltip-follow-cursor') || false,
|
||||
...(target.getAttribute('data-tooltip-appendto') === 'parent' ? {appendTo: 'parent'} : {}),
|
||||
...(target.getAttribute('data-tooltip-interactive') === 'true' ? {interactive: true, aria: {content: 'describedby', expanded: false}} : {}),
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue