Adding some LitElements including DynamicTableFormElement
This commit is contained in:
parent
2638e137b3
commit
0fe9fb4dca
@ -0,0 +1,42 @@
|
|||||||
|
import { html, LitElement } from 'lit'
|
||||||
|
import { repeat } from 'lit-html/directives/repeat.js'
|
||||||
|
import { customElement, property } from 'lit/decorators.js'
|
||||||
|
|
||||||
|
|
||||||
|
@customElement('channel-configuration')
|
||||||
|
export class ChannelConfigurationElement extends LitElement {
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public list: string[] = ["foo", "bar", "baz"]
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public newEl: string = 'change_me'
|
||||||
|
|
||||||
|
createRenderRoot = () => {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<ul>
|
||||||
|
${repeat(this.list, (el: string, index) => html`<li>${el}<button @click=${this._removeFromList(index)}>remove</button></li>`
|
||||||
|
)}
|
||||||
|
<li><input .value=${this.newEl}/><button @click=${this._addToList(this.newEl)}>add</button></li>
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addToList(newEl: string) {
|
||||||
|
return () => {
|
||||||
|
this.list.push(newEl)
|
||||||
|
this.requestUpdate('list')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _removeFromList(index: number) {
|
||||||
|
return () => {
|
||||||
|
this.list.splice(index, 1)
|
||||||
|
this.requestUpdate('list')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
313
client/common/configuration/templates/DynamicTableFormElement.ts
Normal file
313
client/common/configuration/templates/DynamicTableFormElement.ts
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
import { html, LitElement, TemplateResult } from 'lit'
|
||||||
|
import { repeat } from 'lit/directives/repeat.js'
|
||||||
|
import { customElement, property, state } from 'lit/decorators.js'
|
||||||
|
|
||||||
|
type DynamicTableAcceptedTypes = number | string | boolean | Date
|
||||||
|
|
||||||
|
type DynamicTableAcceptedInputTypes = 'textarea'
|
||||||
|
| 'select'
|
||||||
|
| 'checkbox'
|
||||||
|
| 'range'
|
||||||
|
| 'color'
|
||||||
|
| 'date'
|
||||||
|
| 'datetime'
|
||||||
|
| 'datetime-local'
|
||||||
|
| 'email'
|
||||||
|
| 'file'
|
||||||
|
| 'image'
|
||||||
|
| 'month'
|
||||||
|
| 'number'
|
||||||
|
| 'password'
|
||||||
|
| 'tel'
|
||||||
|
| 'text'
|
||||||
|
| 'time'
|
||||||
|
| 'url'
|
||||||
|
| 'week'
|
||||||
|
|
||||||
|
|
||||||
|
interface CellDataSchema {
|
||||||
|
min?: number
|
||||||
|
max?: number
|
||||||
|
minlength?: number
|
||||||
|
maxlength?: number
|
||||||
|
size?: number
|
||||||
|
label?: string
|
||||||
|
options?: { [key: string]: string }
|
||||||
|
inputType?: DynamicTableAcceptedInputTypes
|
||||||
|
default?: DynamicTableAcceptedTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dynamic-table-form')
|
||||||
|
export class DynamicTableFormElement extends LitElement {
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public header: { [key : string]: TemplateResult<1> } = {}
|
||||||
|
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public schema: { [key : string]: CellDataSchema } = {}
|
||||||
|
|
||||||
|
|
||||||
|
@property({ reflect: true })
|
||||||
|
public rows: { _id: number; [key : string]: DynamicTableAcceptedTypes }[] = []
|
||||||
|
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public formName: string = ''
|
||||||
|
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _lastRowId = 1
|
||||||
|
|
||||||
|
createRenderRoot = () => {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getDefaultRow = () => {
|
||||||
|
return Object.fromEntries([...Object.entries(this.schema).map((entry) => [entry[0], entry[1].default ?? '']), ['_id', this._lastRowId++]])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addRow = () => {
|
||||||
|
this.rows.push(this._getDefaultRow())
|
||||||
|
|
||||||
|
this.requestUpdate('rows')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private _removeRow = (rowId: number) => {
|
||||||
|
this.rows = this.rows.filter((x) => x._id != rowId)
|
||||||
|
|
||||||
|
this.requestUpdate('rows')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render = () => {
|
||||||
|
const inputId = `peertube-livechat-${this.formName.replaceAll('_','-')}-table`
|
||||||
|
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12 col-lg-4 col-xl-3">
|
||||||
|
<h2>Bot command #1</h2>
|
||||||
|
<p>You can configure the bot to respond to commands. A command is a message starting with a "!", like for example "!help" that calls the "help" command. For more information about how to configure this feature, please refer to the documentation by clicking on the help button.</p>
|
||||||
|
<a href="https://livingston.frama.io/peertube-plugin-livechat/documentation/user/streamers/bot/commands/" target="_blank" title="Online help" class="orange-button peertube-button-link">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 4.233 4.233">
|
||||||
|
<path style="display:inline;opacity:.998;fill:none;fill-opacity:1;stroke:currentColor;stroke-width:.529167;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M1.48 1.583V.86c0-.171.085-.31.19-.31h.893c.106 0 .19.139.19.31v.838c0 .171-.107.219-.19.284l-.404.314c-.136.106-.219.234-.221.489l-.003.247"></path>
|
||||||
|
<path style="display:inline;fill:currentColor;stroke-width:.235169" d="M1.67 3.429h.529v.597H1.67z"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-lg-8 col-xl-9">
|
||||||
|
<table class="table table-striped table-hover table-sm" id=${inputId}>
|
||||||
|
${this._renderHeader()}
|
||||||
|
<tbody>
|
||||||
|
${repeat(this.rows, this._renderDataRow)}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr><td><button @click=${this._addRow}>Add Row</button></td></tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
${JSON.stringify(this.rows)}
|
||||||
|
`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderHeader = () => {
|
||||||
|
return html`<thead><tr><th scope="col">#</th>${Object.values(this.header).map(this._renderHeaderCell)}<th scope="col">Remove Row</th></tr></thead>`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderHeaderCell = (headerCellData: TemplateResult<1> | any) => {
|
||||||
|
return html`<th scope="col">${headerCellData}</th>`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderDataRow = (rowData: { _id: number; [key : string]: DynamicTableAcceptedTypes }) => {
|
||||||
|
if (!rowData._id) {
|
||||||
|
rowData._id = this._lastRowId++
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputId = `peertube-livechat-${this.formName.replaceAll('_','-')}-row-${rowData._id}`
|
||||||
|
|
||||||
|
return html`<tr id=${inputId}><td class="form-group">${rowData._id}</td>${repeat(Object.entries(rowData).filter(([k,v]) => k != '_id'), (data) => this.renderDataCell(data, rowData._id))}<td class="form-group"><button @click=${() => this._removeRow(rowData._id)}>Remove</button></td></tr>`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDataCell = (property: [string, DynamicTableAcceptedTypes], rowId: number) => {
|
||||||
|
const [propertyName, propertyValue] = property
|
||||||
|
const propertySchema = this.schema[propertyName] ?? {}
|
||||||
|
|
||||||
|
let formElement
|
||||||
|
|
||||||
|
const inputName = `${this.formName.replaceAll('-','_')}_${propertyName.toString().replaceAll('-','_')}_${rowId}`
|
||||||
|
const inputId = `peertube-livechat-${this.formName.replaceAll('_','-')}-${propertyName.toString().replaceAll('_','-')}-${rowId}`
|
||||||
|
|
||||||
|
switch (propertyValue.constructor) {
|
||||||
|
case String:
|
||||||
|
switch (propertySchema.inputType) {
|
||||||
|
case undefined:
|
||||||
|
propertySchema.inputType = 'text'
|
||||||
|
|
||||||
|
case 'text':
|
||||||
|
case 'color':
|
||||||
|
case 'date':
|
||||||
|
case 'datetime':
|
||||||
|
case 'datetime-local':
|
||||||
|
case 'email':
|
||||||
|
case 'file':
|
||||||
|
case 'image':
|
||||||
|
case 'month':
|
||||||
|
case 'number':
|
||||||
|
case 'password':
|
||||||
|
case 'range':
|
||||||
|
case 'tel':
|
||||||
|
case 'time':
|
||||||
|
case 'url':
|
||||||
|
case 'week':
|
||||||
|
formElement = html`<input
|
||||||
|
type=${propertySchema.inputType}
|
||||||
|
name=${inputName}
|
||||||
|
class="form-control"
|
||||||
|
id=${inputId}
|
||||||
|
min=${propertySchema?.min}
|
||||||
|
max=${propertySchema?.max}
|
||||||
|
minlength=${propertySchema?.minlength}
|
||||||
|
maxlength=${propertySchema?.maxlength}
|
||||||
|
@oninput=${(event: InputEvent) => this._updatePropertyFromValue(event, propertyName, rowId)}
|
||||||
|
.value=${propertyValue}
|
||||||
|
/>`
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'textarea':
|
||||||
|
formElement = html`<textarea
|
||||||
|
name=${inputName}
|
||||||
|
class="form-control"
|
||||||
|
id=${inputId}
|
||||||
|
min=${propertySchema?.min}
|
||||||
|
max=${propertySchema?.max}
|
||||||
|
minlength=${propertySchema?.minlength}
|
||||||
|
maxlength=${propertySchema?.maxlength}
|
||||||
|
@oninput=${(event: InputEvent) => this._updatePropertyFromValue(event, propertyName, rowId)}
|
||||||
|
.value=${propertyValue}
|
||||||
|
></textarea>`
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'select':
|
||||||
|
formElement = html`<select class="form-select" aria-label="Default select example">
|
||||||
|
<option ?selected=${!propertyValue}>${propertySchema?.label ?? 'Choose your option'}</option>
|
||||||
|
${Object.entries(propertySchema?.options ?? {})?.map(([value,name]) => html`<option ?selected=${propertyValue === value} value=${value}>${name}</option>`)}
|
||||||
|
</select>`
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case Date:
|
||||||
|
switch (propertySchema.inputType) {
|
||||||
|
case undefined:
|
||||||
|
propertySchema.inputType = 'datetime'
|
||||||
|
|
||||||
|
case 'date':
|
||||||
|
case 'datetime':
|
||||||
|
case 'datetime-local':
|
||||||
|
case 'time':
|
||||||
|
formElement = html`<input
|
||||||
|
type=${propertySchema.inputType}
|
||||||
|
name=${inputName}
|
||||||
|
class="form-control"
|
||||||
|
id=${inputId}
|
||||||
|
min=${propertySchema?.min}
|
||||||
|
max=${propertySchema?.max}
|
||||||
|
minlength=${propertySchema?.minlength}
|
||||||
|
maxlength=${propertySchema?.maxlength}
|
||||||
|
@oninput=${(event: InputEvent) => this._updatePropertyFromValue(event, propertyName, rowId)}
|
||||||
|
.value=${propertyValue}
|
||||||
|
/>`
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case Number:
|
||||||
|
switch (propertySchema.inputType) {
|
||||||
|
case undefined:
|
||||||
|
propertySchema.inputType = 'number'
|
||||||
|
|
||||||
|
case 'number':
|
||||||
|
case 'range':
|
||||||
|
formElement = html`<input
|
||||||
|
type=${propertySchema.inputType}
|
||||||
|
name=${inputName}
|
||||||
|
class="form-control"
|
||||||
|
id=${inputId}
|
||||||
|
min=${propertySchema?.min}
|
||||||
|
max=${propertySchema?.max}
|
||||||
|
minlength=${propertySchema?.minlength}
|
||||||
|
maxlength=${propertySchema?.maxlength}
|
||||||
|
@oninput=${(event: InputEvent) => this._updatePropertyFromValue(event, propertyName, rowId)}
|
||||||
|
.value=${propertyValue}
|
||||||
|
/>`
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case Boolean:
|
||||||
|
switch (propertySchema.inputType) {
|
||||||
|
case undefined:
|
||||||
|
propertySchema.inputType = 'checkbox'
|
||||||
|
|
||||||
|
case 'checkbox':
|
||||||
|
formElement = html`<input
|
||||||
|
type="checkbox"
|
||||||
|
name=${inputName}
|
||||||
|
class="form-check-input"
|
||||||
|
id=${inputId}
|
||||||
|
@oninput=${(event: InputEvent) => this._updatePropertyFromValue(event, propertyName, rowId)}
|
||||||
|
value=""
|
||||||
|
?checked=${propertyValue}
|
||||||
|
/>`
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formElement) {
|
||||||
|
console.warn(`value type '${propertyValue.constructor}' is incompatible with field type '${propertySchema.inputType}' for form entry '${propertyName.toString()}'.`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log
|
||||||
|
|
||||||
|
return html`<td class="form-group">${formElement}</td>`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_updatePropertyFromValue(event: InputEvent, propertyName: string, rowId : number) {
|
||||||
|
let target = event?.target as (HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement)
|
||||||
|
|
||||||
|
if(target?.value) {
|
||||||
|
for(let row of this.rows) {
|
||||||
|
if(row._id === rowId) {
|
||||||
|
row[propertyName] = target?.value
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(`Could not update property : Did not find a property named '${propertyName}' in row '${rowId}'`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn(`Could not update property : Target or value was undefined`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -74,18 +74,18 @@
|
|||||||
<table class="col-12 col-lg-4 col-xl-3 forbidden_words_table">
|
<table class="col-12 col-lg-4 col-xl-3 forbidden_words_table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{forbiddenWords}} <span class="form-group-description">{{forbiddenWordsDesc2}}</th>
|
<th scope="col">{{forbiddenWords}} <span class="form-group-description">{{forbiddenWordsDesc2}}</span></th>
|
||||||
<th scope="col">{{forbiddenWordsRegexp}} <span class="form-group-description">{{forbiddenWordsRegexpDesc}}</span></th>
|
<th scope="col">{{forbiddenWordsRegexp}} <span class="form-group-description">{{forbiddenWordsRegexpDesc}}</span></th>
|
||||||
<th scope="col">{{forbiddenWordsApplyToModerators}} <span class="form-group-description">{{forbiddenWordsApplyToModeratorsDesc}}</span></th>
|
<th scope="col">{{forbiddenWordsApplyToModerators}} <span class="form-group-description">{{forbiddenWordsApplyToModeratorsDesc}}</span></th>
|
||||||
<th scope="col">{{forbiddenWordsLabel}} <span class="form-group-description">{{forbiddenWordsLabelDesc}}</th>
|
<th scope="col">{{forbiddenWordsLabel}} <span class="form-group-description">{{forbiddenWordsLabelDesc}}</span></th>
|
||||||
<th scope="col">{{forbiddenWordsReason}} <span class="form-group-description">{{forbiddenWordsReasonDesc}}</th>
|
<th scope="col">{{forbiddenWordsReason}} <span class="form-group-description">{{forbiddenWordsReasonDesc}}</span></th>
|
||||||
<th scope="col">{{forbiddenWordsComments}} <span class="form-group-description">{{forbiddenWordsCommentsDesc}}</th>
|
<th scope="col">{{forbiddenWordsComments}} <span class="form-group-description">{{forbiddenWordsCommentsDesc}}</span></th>
|
||||||
<th scope="col">Remove <span class="form-group-description">Remove Row</th>
|
<th scope="col">Remove <span class="form-group-description">Remove Row</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{{#forbiddenWordsArray}}{{! iterating on forbiddenWordsArray to display N fields }}
|
{{#forbiddenWordsArray}}{{! iterating on forbiddenWordsArray to display N fields }}
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="button.peertube-livechat-forbidden-words-row-{{fieldNumber}}">
|
<tr class="peertube-livechat-forbidden-words-row-{{fieldNumber}}">
|
||||||
<td>
|
<td>
|
||||||
{{! warning: don't add extra line break in textarea! }}
|
{{! warning: don't add extra line break in textarea! }}
|
||||||
<textarea
|
<textarea
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||||
import { localizedHelpUrl } from '../../../utils/help'
|
import { localizedHelpUrl } from '../../../utils/help'
|
||||||
import { helpButtonSVG } from '../../../videowatch/buttons'
|
import { helpButtonSVG } from '../../../videowatch/buttons'
|
||||||
import { vivifyConfigurationChannel, getConfigurationChannelViewData } from './logic/channel'
|
import { getConfigurationChannelViewData } from './logic/channel'
|
||||||
import { TemplateResult, html } from 'lit'
|
import { TemplateResult, html } from 'lit'
|
||||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js'
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js'
|
||||||
// Must use require for mustache, import seems buggy.
|
// Must use require for mustache, import seems buggy.
|
||||||
const Mustache = require('mustache')
|
const Mustache = require('mustache')
|
||||||
|
import './DynamicTableFormElement'
|
||||||
|
import './ChannelConfigurationElement'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the configuration settings page for a given channel,
|
* Renders the configuration settings page for a given channel,
|
||||||
@ -25,13 +27,92 @@ async function renderConfigurationChannel (
|
|||||||
rootEl: HTMLElement
|
rootEl: HTMLElement
|
||||||
): Promise<TemplateResult> {
|
): Promise<TemplateResult> {
|
||||||
try {
|
try {
|
||||||
const view = await getConfigurationChannelViewData(registerClientOptions, channelId)
|
const view : {[key: string] : any} = await getConfigurationChannelViewData(registerClientOptions, channelId)
|
||||||
await fillViewHelpButtons(registerClientOptions, view)
|
await fillViewHelpButtons(registerClientOptions, view)
|
||||||
await fillLabels(registerClientOptions, view)
|
await fillLabels(registerClientOptions, view)
|
||||||
|
|
||||||
return html`${unsafeHTML(Mustache.render(MUSTACHE_CONFIGURATION_CHANNEL, view))}`
|
//await vivifyConfigurationChannel(registerClientOptions, rootEl, channelId)
|
||||||
|
|
||||||
await vivifyConfigurationChannel(registerClientOptions, rootEl, channelId)
|
let tableHeader = {
|
||||||
|
words: html`${view.forbiddenWords}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsDesc}></div>`,
|
||||||
|
regex: html`${view.forbiddenWordsRegexp}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsRegexpDesc}></div>`,
|
||||||
|
applyToModerators: html`${view.forbiddenWordsApplyToModerators}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsApplyToModeratorsDesc}></div>`,
|
||||||
|
label: html`${view.forbiddenWordsLabel}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsLabelDesc}></div>`,
|
||||||
|
reason: html`${view.forbiddenWordsReason}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsReasonDesc}></div>`,
|
||||||
|
comments: html`${view.forbiddenWordsComments}<div data-toggle="tooltip" data-placement="bottom" data-html="true" title=${view.forbiddenWordsCommentsDesc}></div>`,
|
||||||
|
}
|
||||||
|
let tableSchema = {
|
||||||
|
words: {
|
||||||
|
inputType: 'text',
|
||||||
|
default: 'helloqwesad'
|
||||||
|
},
|
||||||
|
regex: {
|
||||||
|
inputType: 'text',
|
||||||
|
default: 'helloaxzca'
|
||||||
|
},
|
||||||
|
applyToModerators: {
|
||||||
|
inputType: 'checkbox',
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
inputType: 'text',
|
||||||
|
default: 'helloasx'
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
inputType: 'select',
|
||||||
|
default: 'transphobia',
|
||||||
|
label: 'choose your poison',
|
||||||
|
options: {'racism': 'Racism', 'sexism': 'Sexism', 'transphobia': 'Transphobia', 'bigotry': 'Bigotry'}
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
inputType: 'textarea',
|
||||||
|
default: `Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||||
|
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||||
|
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||||
|
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
||||||
|
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
||||||
|
culpa qui officia deserunt mollit anim id est laborum.`
|
||||||
|
},
|
||||||
|
}
|
||||||
|
let tableRows = [
|
||||||
|
{
|
||||||
|
words: 'teweqwst',
|
||||||
|
regex: 'tesdgst',
|
||||||
|
applyToModerators: false,
|
||||||
|
label: 'teswet',
|
||||||
|
reason: 'sexism',
|
||||||
|
comments: 'tsdaswest',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
words: 'tedsadst',
|
||||||
|
regex: 'tezxccst',
|
||||||
|
applyToModerators: true,
|
||||||
|
label: 'tewest',
|
||||||
|
reason: 'racism',
|
||||||
|
comments: 'tesxzct',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
words: 'tesadsdxst',
|
||||||
|
regex: 'dsfsdf',
|
||||||
|
applyToModerators: false,
|
||||||
|
label: 'tesdadst',
|
||||||
|
reason: 'bigotry',
|
||||||
|
comments: 'tsadest',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return html`${unsafeHTML(Mustache.render(MUSTACHE_CONFIGURATION_CHANNEL, view))}
|
||||||
|
<div class="container">
|
||||||
|
<channel-configuration></channel-configuration>
|
||||||
|
<dynamic-table-form
|
||||||
|
.header=${tableHeader}
|
||||||
|
.schema=${tableSchema}
|
||||||
|
.rows=${tableRows}
|
||||||
|
.formName=${'dynamic-table-form'}
|
||||||
|
>
|
||||||
|
</dynamic-table-form>
|
||||||
|
</div>${JSON.stringify(tableRows)}`
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
registerClientOptions.peertubeHelpers.notifier.error(err.toString())
|
registerClientOptions.peertubeHelpers.notifier.error(err.toString())
|
||||||
return html``
|
return html``
|
||||||
@ -40,7 +121,7 @@ async function renderConfigurationChannel (
|
|||||||
|
|
||||||
async function fillViewHelpButtons (
|
async function fillViewHelpButtons (
|
||||||
registerClientOptions: RegisterClientOptions,
|
registerClientOptions: RegisterClientOptions,
|
||||||
view: any
|
view: {[key: string]: string}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const title = await registerClientOptions.peertubeHelpers.translate(LOC_ONLINE_HELP)
|
const title = await registerClientOptions.peertubeHelpers.translate(LOC_ONLINE_HELP)
|
||||||
|
|
||||||
@ -67,7 +148,7 @@ async function fillViewHelpButtons (
|
|||||||
|
|
||||||
async function fillLabels (
|
async function fillLabels (
|
||||||
registerClientOptions: RegisterClientOptions,
|
registerClientOptions: RegisterClientOptions,
|
||||||
view: any
|
view: {[key: string] : string}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { peertubeHelpers } = registerClientOptions
|
const { peertubeHelpers } = registerClientOptions
|
||||||
view.title = await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TITLE)
|
view.title = await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TITLE)
|
||||||
|
@ -14,7 +14,7 @@ import { getBaseRoute } from '../../../../utils/uri'
|
|||||||
async function getConfigurationChannelViewData (
|
async function getConfigurationChannelViewData (
|
||||||
registerClientOptions: RegisterClientOptions,
|
registerClientOptions: RegisterClientOptions,
|
||||||
channelId: string
|
channelId: string
|
||||||
): Promise<Object> {
|
): Promise<{[key: string] : any}> {
|
||||||
if (!channelId || !/^\d+$/.test(channelId)) {
|
if (!channelId || !/^\d+$/.test(channelId)) {
|
||||||
throw new Error('Missing or invalid channel id.')
|
throw new Error('Missing or invalid channel id.')
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "es6",
|
"experimentalDecorators": true,
|
||||||
|
"module": "es2022",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es2022",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
@ -12,7 +13,7 @@
|
|||||||
"noImplicitThis": true, // should already be true because of strict:true
|
"noImplicitThis": true, // should already be true because of strict:true
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"strictBindCallApply": true, // should already be true because of strict:true
|
"strictBindCallApply": true, // should already be true because of strict:true
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": false,
|
||||||
"allowSyntheticDefaultImports": true, // Seems necessary for peertube types to work
|
"allowSyntheticDefaultImports": true, // Seems necessary for peertube types to work
|
||||||
"isolatedModules": true, // Needed by esbuild https://esbuild.github.io/content-types/#isolated-modules
|
"isolatedModules": true, // Needed by esbuild https://esbuild.github.io/content-types/#isolated-modules
|
||||||
"esModuleInterop": true, // Needed by esbuild https://esbuild.github.io/content-types/#es-module-interop
|
"esModuleInterop": true, // Needed by esbuild https://esbuild.github.io/content-types/#es-module-interop
|
||||||
|
28
package-lock.json
generated
28
package-lock.json
generated
@ -53,7 +53,7 @@
|
|||||||
"stylelint-config-recommended-scss": "^5.0.1",
|
"stylelint-config-recommended-scss": "^5.0.1",
|
||||||
"stylelint-config-standard-scss": "^2.0.1",
|
"stylelint-config-standard-scss": "^2.0.1",
|
||||||
"svgo": "^2.8.0",
|
"svgo": "^2.8.0",
|
||||||
"typescript": "^4.3.5",
|
"typescript": "^5.0.0",
|
||||||
"yaml": "^2.2.1"
|
"yaml": "^2.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -5448,9 +5448,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001596",
|
"version": "1.0.30001617",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz",
|
||||||
"integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==",
|
"integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -12007,16 +12007,16 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.3.5",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.2.0"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/uid-safe": {
|
"node_modules/uid-safe": {
|
||||||
@ -16575,9 +16575,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001596",
|
"version": "1.0.30001617",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz",
|
||||||
"integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ=="
|
"integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA=="
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
@ -21410,9 +21410,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.3.5",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uid-safe": {
|
"uid-safe": {
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
"stylelint-config-recommended-scss": "^5.0.1",
|
"stylelint-config-recommended-scss": "^5.0.1",
|
||||||
"stylelint-config-standard-scss": "^2.0.1",
|
"stylelint-config-standard-scss": "^2.0.1",
|
||||||
"svgo": "^2.8.0",
|
"svgo": "^2.8.0",
|
||||||
"typescript": "^4.3.5",
|
"typescript": "^5.0.0",
|
||||||
"yaml": "^2.2.1"
|
"yaml": "^2.2.1"
|
||||||
},
|
},
|
||||||
"engine": {
|
"engine": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user