Various improvements:

* CSS cleaning
* disabling buttons during loading
* reset buttons on forms
This commit is contained in:
John Livingston 2024-06-11 15:05:20 +02:00
parent e84782f346
commit 75ac7a1052
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
3 changed files with 102 additions and 35 deletions

View File

@ -72,7 +72,10 @@ $small-view: 800px;
} }
input[type="submit"], input[type="submit"],
input[type="reset"] { input[type="reset"],
button[type="submit"],
button[type="reset"],
.peertube-plugin-livechat-configuration-actions button {
// Peertube rounded-line-height-1-5 mixins // Peertube rounded-line-height-1-5 mixins
line-height: $button-calc-line-height; line-height: $button-calc-line-height;
@ -86,7 +89,9 @@ $small-view: 800px;
font-size: $button-font-size; font-size: $button-font-size;
} }
input[type="submit"] { input[type="submit"],
button[type="submit"],
.peertube-plugin-livechat-configuration-actions button {
// Peertube orange-button mixin // Peertube orange-button mixin
&, &,
&:active, &:active,
@ -108,7 +113,8 @@ $small-view: 800px;
} }
} }
input[type="reset"] { input[type="reset"],
button[type="reset"] {
// Peertube grey-button mixin // Peertube grey-button mixin
background-color: var(--greyBackgroundColor); background-color: var(--greyBackgroundColor);
color: var(--greyForegroundColor); color: var(--greyForegroundColor);

View File

@ -36,19 +36,40 @@ export class ChannelConfigurationElement extends LivechatElement {
@state() @state()
public _validationError?: ValidationError public _validationError?: ValidationError
private readonly _asyncTaskRender = new Task(this, { @state()
task: async ([registerClientOptions]) => { private _actionDisabled: boolean = false
if (registerClientOptions) {
this._channelDetailsService = new ChannelDetailsService(registerClientOptions) private _asyncTaskRender: Task
this._channelConfiguration = await this._channelDetailsService.fetchConfiguration(this.channelId ?? 0)
} constructor () {
}, super()
args: () => [this.registerClientOptions] this._asyncTaskRender = this._initTask()
}) }
protected _initTask (): Task {
return new Task(this, {
task: async ([registerClientOptions]) => {
if (registerClientOptions) {
this._channelDetailsService = new ChannelDetailsService(registerClientOptions)
this._channelConfiguration = await this._channelDetailsService.fetchConfiguration(this.channelId ?? 0)
this._actionDisabled = false // in case of reset
}
},
args: () => [this.registerClientOptions]
})
}
private async _reset (event?: Event): Promise<void> {
event?.preventDefault()
this._actionDisabled = true
this._asyncTaskRender = this._initTask()
this.requestUpdate()
}
private readonly _saveConfig = async (event?: Event): Promise<void> => { private readonly _saveConfig = async (event?: Event): Promise<void> => {
event?.preventDefault() event?.preventDefault()
if (this._channelDetailsService && this._channelConfiguration) { if (this._channelDetailsService && this._channelConfiguration) {
this._actionDisabled = true
this._channelDetailsService.saveOptions(this._channelConfiguration.channel.id, this._channelDetailsService.saveOptions(this._channelConfiguration.channel.id,
this._channelConfiguration.configuration) this._channelConfiguration.configuration)
.then(() => { .then(() => {
@ -72,6 +93,9 @@ export class ChannelConfigurationElement extends LivechatElement {
) )
this.requestUpdate('_validationError') this.requestUpdate('_validationError')
}) })
.finally(() => {
this._actionDisabled = false
})
} }
} }
@ -398,7 +422,12 @@ export class ChannelConfigurationElement extends LivechatElement {
</div> </div>
`} `}
<div class="form-group mt-5"> <div class="form-group mt-5">
<input type="submit" class="peertube-button-link orange-button" value=${ptTr(LOC_SAVE)} /> <button type="reset" @click=${this._reset} ?disabled=${this._actionDisabled}>
${ptTr(LOC_CANCEL)}
</button>
<button type="submit" ?disabled=${this._actionDisabled}>
${ptTr(LOC_SAVE)}
</button>
</div> </div>
</form> </form>
</div>` </div>`

View File

@ -37,6 +37,16 @@ export class ChannelEmojisElement extends LivechatElement {
@state() @state()
private _validationError?: ValidationError private _validationError?: ValidationError
@state()
private _actionDisabled: boolean = false
private _asyncTaskRender: Task
constructor () {
super()
this._asyncTaskRender = this._initTask()
}
protected override render = (): unknown => { protected override render = (): unknown => {
const tableHeaderList: DynamicFormHeader = { const tableHeaderList: DynamicFormHeader = {
sn: { sn: {
@ -84,14 +94,22 @@ export class ChannelEmojisElement extends LivechatElement {
<div class="peertube-plugin-livechat-configuration-actions"> <div class="peertube-plugin-livechat-configuration-actions">
${ ${
this._channelEmojisConfiguration?.emojis?.customEmojis?.length this._channelEmojisConfiguration?.emojis?.customEmojis?.length
? html`<button class="peertube-button-link orange-button" @click=${this._exportEmojis}> ? html`
<button
@click=${this._exportEmojis}
?disabled=${this._actionDisabled}
>
${ptTr(LOC_ACTION_EXPORT)} ${ptTr(LOC_ACTION_EXPORT)}
</button>` </button>`
: '' : ''
} }
${ ${
(this._channelEmojisConfiguration?.emojis?.customEmojis?.length ?? 0) < maxEmojisPerChannel (this._channelEmojisConfiguration?.emojis?.customEmojis?.length ?? 0) < maxEmojisPerChannel
? html`<button class="peertube-button-link orange-button" @click=${this._importEmojis}> ? html`
<button
@click=${this._importEmojis}
?disabled=${this._actionDisabled}
>
${ptTr(LOC_ACTION_IMPORT)} ${ptTr(LOC_ACTION_IMPORT)}
</button>` </button>`
: '' : ''
@ -123,7 +141,10 @@ export class ChannelEmojisElement extends LivechatElement {
></livechat-dynamic-table-form> ></livechat-dynamic-table-form>
</div> </div>
<div class="form-group mt-5"> <div class="form-group mt-5">
<button type="submit" class="peertube-button-link orange-button"> <button type="reset" @click=${this._reset} ?disabled=${this._actionDisabled}>
${ptTr(LOC_CANCEL)}
</button>
<button type="submit" ?disabled=${this._actionDisabled}>
${ptTr(LOC_SAVE)} ${ptTr(LOC_SAVE)}
</button> </button>
</div> </div>
@ -136,19 +157,29 @@ export class ChannelEmojisElement extends LivechatElement {
}) })
} }
private readonly _asyncTaskRender = new Task(this, { protected _initTask (): Task {
task: async () => { return new Task(this, {
if (!this.registerClientOptions) { task: async () => {
throw new Error('Missing client options') if (!this.registerClientOptions) {
} throw new Error('Missing client options')
if (!this.channelId) { }
throw new Error('Missing channelId') if (!this.channelId) {
} throw new Error('Missing channelId')
this._channelDetailsService = new ChannelDetailsService(this.registerClientOptions) }
this._channelEmojisConfiguration = await this._channelDetailsService.fetchEmojisConfiguration(this.channelId) this._channelDetailsService = new ChannelDetailsService(this.registerClientOptions)
}, this._channelEmojisConfiguration = await this._channelDetailsService.fetchEmojisConfiguration(this.channelId)
args: () => [] this._actionDisabled = false // in case of reset
}) },
args: () => []
})
}
private async _reset (ev?: Event): Promise<void> {
ev?.preventDefault()
this._actionDisabled = true
this._asyncTaskRender = this._initTask()
this.requestUpdate()
}
private async _saveEmojis (ev?: Event): Promise<void> { private async _saveEmojis (ev?: Event): Promise<void> {
ev?.preventDefault() ev?.preventDefault()
@ -161,6 +192,7 @@ export class ChannelEmojisElement extends LivechatElement {
} }
try { try {
this._actionDisabled = true
await this._channelDetailsService.saveEmojisConfiguration(this.channelId, this._channelEmojisConfiguration.emojis) await this._channelDetailsService.saveEmojisConfiguration(this.channelId, this._channelEmojisConfiguration.emojis)
this._validationError = undefined this._validationError = undefined
peertubeHelpers.notifier.info(await peertubeHelpers.translate(LOC_SUCCESSFULLY_SAVED)) peertubeHelpers.notifier.info(await peertubeHelpers.translate(LOC_SUCCESSFULLY_SAVED))
@ -177,13 +209,14 @@ export class ChannelEmojisElement extends LivechatElement {
msg ??= await peertubeHelpers.translate(LOC_ERROR) msg ??= await peertubeHelpers.translate(LOC_ERROR)
peertubeHelpers.notifier.error(msg) peertubeHelpers.notifier.error(msg)
this.requestUpdate('_validationError') this.requestUpdate('_validationError')
} finally {
this._actionDisabled = false
} }
} }
private async _importEmojis (ev: Event): Promise<void> { private async _importEmojis (ev: Event): Promise<void> {
ev.preventDefault() ev.preventDefault()
const b: HTMLElement | null = ev.target && 'tagName' in ev.target ? ev.target as HTMLElement : null this._actionDisabled = true
b?.setAttribute('disabled', '')
try { try {
// download a json file: // download a json file:
const file = await new Promise<File>((resolve, reject) => { const file = await new Promise<File>((resolve, reject) => {
@ -256,14 +289,13 @@ export class ChannelEmojisElement extends LivechatElement {
} catch (err: any) { } catch (err: any) {
this.registerClientOptions?.peertubeHelpers.notifier.error(err.toString()) this.registerClientOptions?.peertubeHelpers.notifier.error(err.toString())
} finally { } finally {
b?.removeAttribute('disabled') this._actionDisabled = false
} }
} }
private async _exportEmojis (ev: Event): Promise<void> { private async _exportEmojis (ev: Event): Promise<void> {
ev.preventDefault() ev.preventDefault()
const b: HTMLElement | null = ev.target && 'tagName' in ev.target ? ev.target as HTMLElement : null this._actionDisabled = true
b?.setAttribute('disabled', '')
try { try {
const result: ChannelEmojisConfiguration['emojis']['customEmojis'] = [] const result: ChannelEmojisConfiguration['emojis']['customEmojis'] = []
for (const ed of this._channelEmojisConfiguration?.emojis?.customEmojis ?? []) { for (const ed of this._channelEmojisConfiguration?.emojis?.customEmojis ?? []) {
@ -293,7 +325,7 @@ export class ChannelEmojisElement extends LivechatElement {
console.error(err) console.error(err)
this.registerClientOptions?.peertubeHelpers.notifier.error(err.toString()) this.registerClientOptions?.peertubeHelpers.notifier.error(err.toString())
} finally { } finally {
b?.removeAttribute('disabled') this._actionDisabled = false
} }
} }