Compare commits
88 Commits
file-group
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
2bd207835a | 3 years ago |
|
|
b212e91413 | 3 years ago |
|
|
a333dcd9f1 | 3 years ago |
|
|
84d4836daa | 3 years ago |
|
|
45956133ea | 3 years ago |
|
|
711720f49d | 3 years ago |
|
|
2c3b1d8e14 | 3 years ago |
|
|
5ecd17fc6a | 3 years ago |
|
|
84e31943a2 | 3 years ago |
|
|
d5138ae491 | 3 years ago |
|
|
b66e298ac8 | 3 years ago |
|
|
8696ad8228 | 3 years ago |
|
|
3cc25e6d37 | 3 years ago |
|
|
806a44c107 | 3 years ago |
|
|
3081900ec8 | 3 years ago |
|
|
da46a345f8 | 3 years ago |
|
|
ef8a5fbf35 | 3 years ago |
|
|
f7495eb9e4 | 3 years ago |
|
|
e7b3f4ee86 | 3 years ago |
|
|
e58f74b016 | 3 years ago |
|
|
00beac7bd4 | 3 years ago |
|
|
3d25ccd34c | 3 years ago |
|
|
4e45e94934 | 3 years ago |
|
|
646fa8e0af | 3 years ago |
|
|
3e2aa1925e | 3 years ago |
|
|
acfd969c31 | 3 years ago |
|
|
efe43fd7e1 | 3 years ago |
|
|
a37c2e3203 | 3 years ago |
|
|
e7e5cdc500 | 3 years ago |
|
|
c0113e8c71 | 3 years ago |
|
|
03885398c5 | 3 years ago |
|
|
9c67f0c741 | 3 years ago |
|
|
e8857a5406 | 3 years ago |
|
|
bc99762851 | 3 years ago |
|
|
ab343c44c3 | 3 years ago |
|
|
977c329f3a | 3 years ago |
|
|
67fc165526 | 3 years ago |
|
|
346428989f | 3 years ago |
|
|
d28d932a20 | 3 years ago |
|
|
4ac49ff357 | 3 years ago |
|
|
55910452e3 | 3 years ago |
|
|
bc759e5197 | 3 years ago |
|
|
622f6a113d | 3 years ago |
|
|
a15fcc921d | 3 years ago |
|
|
453477b9da | 3 years ago |
|
|
7873c51d48 | 3 years ago |
|
|
a090a11940 | 3 years ago |
|
|
89e6d855c9 | 3 years ago |
|
|
17587dbdc2 | 3 years ago |
|
|
f7cca256a6 | 3 years ago |
|
|
0c42e5c9a8 | 3 years ago |
|
|
d7beb37682 | 3 years ago |
|
|
8893008e94 | 3 years ago |
|
|
2886878ab6 | 3 years ago |
|
|
960bfb0220 | 3 years ago |
|
|
aea9b90dc8 | 3 years ago |
|
|
cdd1cba1e6 | 3 years ago |
|
|
466845e65a | 3 years ago |
|
|
dc7716b4e5 | 3 years ago |
|
|
8a3f084936 | 3 years ago |
|
|
934e6616c4 | 3 years ago |
|
|
1a9f5e9ce4 | 3 years ago |
|
|
9e90b8a3b8 | 3 years ago |
|
|
0622d10db4 | 3 years ago |
|
|
810924b677 | 3 years ago |
|
|
cd467c4443 | 3 years ago |
|
|
287e737c11 | 3 years ago |
|
|
34fb5b07cc | 3 years ago |
|
|
aae3ba6d57 | 3 years ago |
|
|
331b85048b | 3 years ago |
|
|
07fd06f339 | 3 years ago |
|
|
cec083ef39 | 3 years ago |
|
|
895c79130f | 3 years ago |
|
|
ba12ecc7c7 | 3 years ago |
|
|
9e034e2e5e | 3 years ago |
|
|
23a0f309b4 | 3 years ago |
|
|
e767ed78d7 | 3 years ago |
|
|
a9f0e0bd67 | 3 years ago |
|
|
0abc623a00 | 3 years ago |
|
|
6e107c9f87 | 3 years ago |
|
|
44ac8dd595 | 3 years ago |
|
|
60a04047b1 | 3 years ago |
|
|
a5883d746b | 3 years ago |
|
|
9c6213c3e5 | 3 years ago |
|
|
911f90714d | 3 years ago |
|
|
4782c72726 | 3 years ago |
|
|
92365e5d82 | 3 years ago |
|
|
c9a021057b | 3 years ago |
@ -0,0 +1,377 @@
|
|||||||
|
export class PageActions extends HTMLElement {
|
||||||
|
textEn = {
|
||||||
|
download: 'Download',
|
||||||
|
rename: 'Move/Rename',
|
||||||
|
duplicate: 'Duplicate',
|
||||||
|
delete_: 'Delete',
|
||||||
|
settings: 'Settings',
|
||||||
|
confirmDelete: f => (
|
||||||
|
`Are you sure you want to delete ${f}?`
|
||||||
|
),
|
||||||
|
cancel: 'Cancel',
|
||||||
|
alreadyExists: 'There is already a page with that name.',
|
||||||
|
save: 'Guardar',
|
||||||
|
close: 'Close',
|
||||||
|
}
|
||||||
|
|
||||||
|
textEs = {
|
||||||
|
download: 'Descargar',
|
||||||
|
rename: 'Mover/Renombrar',
|
||||||
|
duplicate: 'Duplicar',
|
||||||
|
delete_: 'Borrar',
|
||||||
|
settings: 'Configuración',
|
||||||
|
confirmDelete: f => (
|
||||||
|
`¿Desea borrar ${f}?`
|
||||||
|
),
|
||||||
|
cancel: 'Cancelar',
|
||||||
|
alreadyExists: 'Ya existe una página con ese nombre.',
|
||||||
|
save: 'Guardar',
|
||||||
|
close: 'Cerrar',
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.attachShadow({mode: 'open'})
|
||||||
|
this.language = navigator.language
|
||||||
|
this.dialogWrap = document.createElement('div')
|
||||||
|
this.shadowRoot.append(this.dialogWrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.textContent = `
|
||||||
|
m-dialog::part(footer) {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
this.shadowRoot.appendChild(style)
|
||||||
|
}
|
||||||
|
|
||||||
|
get menuActions() {
|
||||||
|
const baseActions = [
|
||||||
|
{
|
||||||
|
text: this.text.download,
|
||||||
|
click: this.download.bind(this),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.text.rename,
|
||||||
|
click: this.rename.bind(this),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.text.duplicate,
|
||||||
|
click: this.duplicate.bind(this),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.text.delete_,
|
||||||
|
click: this.delete_.bind(this),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (this.page.isGroup) {
|
||||||
|
return [
|
||||||
|
...baseActions,
|
||||||
|
{
|
||||||
|
text: this.text.settings,
|
||||||
|
click: this.settings.bind(this),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
return baseActions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
download() {
|
||||||
|
const text = this.storage.getItem(this.path)
|
||||||
|
const sp = this.path.split('/')
|
||||||
|
const filename = sp[sp.length - 1]
|
||||||
|
const el = document.createElement('a')
|
||||||
|
el.setAttribute(
|
||||||
|
'href',
|
||||||
|
'data:text/plain;charset=utf-8,' +
|
||||||
|
encodeURIComponent(text)
|
||||||
|
)
|
||||||
|
el.setAttribute('download', filename)
|
||||||
|
el.style.display = 'none'
|
||||||
|
this.shadowRoot.appendChild(el)
|
||||||
|
el.click()
|
||||||
|
this.shadowRoot.removeChild(el)
|
||||||
|
}
|
||||||
|
|
||||||
|
rename() {
|
||||||
|
const dialog = document.createElement(
|
||||||
|
'm-dialog'
|
||||||
|
)
|
||||||
|
this.dialogWrap.replaceChildren(dialog)
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.value = this.path
|
||||||
|
input.style.minWidth = '300px'
|
||||||
|
dialog.bodyEl.appendChild(input)
|
||||||
|
let errorEl
|
||||||
|
const bGroup = document.createElement(
|
||||||
|
'm-forms-button-group'
|
||||||
|
)
|
||||||
|
bGroup.addPrimary(this.text.rename, () => {
|
||||||
|
const newPath = input.value
|
||||||
|
const v = this.storage.getItem(newPath)
|
||||||
|
if (v !== null || newPath === this.path) {
|
||||||
|
if (!errorEl) {
|
||||||
|
errorEl = document.createElement('p')
|
||||||
|
errorEl.style.color = 'red'
|
||||||
|
const errText = this.text.alreadyExists
|
||||||
|
errorEl.innerText = errText
|
||||||
|
dialog.bodyEl.appendChild(errorEl)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const sKeyOld = 'settings/page:' + this.path
|
||||||
|
const sKeyNew = 'settings/page:' + newPath
|
||||||
|
const settingsJson = this.storage.getItem(sKeyOld)
|
||||||
|
if (settingsJson ?? true === true) {
|
||||||
|
this.storage.setItem(sKeyNew, settingsJson)
|
||||||
|
this.storage.removeItem(sKeyOld)
|
||||||
|
let settingsData
|
||||||
|
try {
|
||||||
|
settingsData = JSON.parse(settingsJson)
|
||||||
|
} catch (err) {
|
||||||
|
settingsData = {}
|
||||||
|
}
|
||||||
|
if (settingsData?.connections) {
|
||||||
|
for (const dir of ['outbound', 'inbound']) {
|
||||||
|
const otherDir = (
|
||||||
|
dir === 'outbound' ? 'inbound' : 'outbound'
|
||||||
|
)
|
||||||
|
this.applyInverseRename(
|
||||||
|
settingsData, dir, otherDir, this.path, newPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.storage.removeItem(sKeyNew)
|
||||||
|
}
|
||||||
|
this.storage.setItem(
|
||||||
|
newPath,
|
||||||
|
this.storage.getItem(this.path)
|
||||||
|
)
|
||||||
|
this.storage.removeItem(this.path)
|
||||||
|
dialog.close()
|
||||||
|
location.hash = newPath
|
||||||
|
})
|
||||||
|
bGroup.addCancel(this.text.cancel, () => {
|
||||||
|
dialog.close()
|
||||||
|
})
|
||||||
|
dialog.footerEl.appendChild(bGroup)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate() {
|
||||||
|
const dialog = document.createElement(
|
||||||
|
'm-dialog'
|
||||||
|
)
|
||||||
|
this.dialogWrap.replaceChildren(dialog)
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.value = this.path
|
||||||
|
input.style.minWidth = '300px'
|
||||||
|
dialog.bodyEl.appendChild(input)
|
||||||
|
let errorEl
|
||||||
|
const bGroup = document.createElement(
|
||||||
|
'm-forms-button-group'
|
||||||
|
)
|
||||||
|
const btnText = this.text.duplicate
|
||||||
|
bGroup.addPrimary(btnText, () => {
|
||||||
|
const newPath = input.value
|
||||||
|
const v = this.storage.getItem(newPath)
|
||||||
|
if (v !== null || newPath === this.path) {
|
||||||
|
if (!errorEl) {
|
||||||
|
errorEl = document.createElement('p')
|
||||||
|
errorEl.style.color = 'red'
|
||||||
|
const errText = this.text.alreadyExists
|
||||||
|
errorEl.innerText = errText
|
||||||
|
dialog.bodyEl.appendChild(errorEl)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.storage.setItem(
|
||||||
|
newPath,
|
||||||
|
this.storage.getItem(this.path)
|
||||||
|
)
|
||||||
|
this.storage.setItem(
|
||||||
|
'settings/page:' + newPath,
|
||||||
|
this.storage.getItem(this.path) ?? '{}'
|
||||||
|
)
|
||||||
|
dialog.close()
|
||||||
|
location.hash = newPath
|
||||||
|
})
|
||||||
|
bGroup.addCancel(this.text.cancel, () => {
|
||||||
|
dialog.close()
|
||||||
|
})
|
||||||
|
dialog.footerEl.appendChild(bGroup)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_() {
|
||||||
|
const dialog = document.createElement(
|
||||||
|
'm-dialog'
|
||||||
|
)
|
||||||
|
this.dialogWrap.replaceChildren(dialog)
|
||||||
|
const p = document.createElement('p')
|
||||||
|
p.innerText = this.text.confirmDelete(
|
||||||
|
JSON.stringify(this.path)
|
||||||
|
)
|
||||||
|
dialog.bodyEl.appendChild(p)
|
||||||
|
|
||||||
|
const bGroup = document.createElement(
|
||||||
|
'm-forms-button-group'
|
||||||
|
)
|
||||||
|
bGroup.addPrimary(this.text.delete_, () => {
|
||||||
|
this.storage.removeItem(this.path)
|
||||||
|
this.storage.removeItem(
|
||||||
|
'settings/page:' + this.path
|
||||||
|
)
|
||||||
|
location.hash = '/'
|
||||||
|
dialog.close()
|
||||||
|
})
|
||||||
|
bGroup.addCancel(this.text.cancel, () => {
|
||||||
|
dialog.close()
|
||||||
|
})
|
||||||
|
dialog.footerEl.appendChild(bGroup)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
settings() {
|
||||||
|
const dialog = document.createElement(
|
||||||
|
'm-dialog'
|
||||||
|
)
|
||||||
|
this.dialogWrap.replaceChildren(dialog)
|
||||||
|
const settingsEl = document.createElement(
|
||||||
|
'm-settings-page-settings'
|
||||||
|
)
|
||||||
|
settingsEl.cspProfiles = this.cspProfiles
|
||||||
|
settingsEl.path = this.path
|
||||||
|
settingsEl.checkExists = path => (
|
||||||
|
this.storage.getItem(path) !== null
|
||||||
|
)
|
||||||
|
settingsEl.data = this.page.settings
|
||||||
|
const h = document.createElement('h2')
|
||||||
|
h.innerText = this.text.settings
|
||||||
|
dialog.headerEl.append(h)
|
||||||
|
dialog.bodyEl.append(settingsEl)
|
||||||
|
const bGroup = document.createElement(
|
||||||
|
'm-forms-button-group'
|
||||||
|
)
|
||||||
|
bGroup.addPrimary(this.text.save, () => {
|
||||||
|
const settingsData = settingsEl.data
|
||||||
|
this.page.settings = settingsData
|
||||||
|
for (const dir of ['outbound', 'inbound']) {
|
||||||
|
const otherDir = (
|
||||||
|
dir === 'outbound' ? 'inbound' : 'outbound'
|
||||||
|
)
|
||||||
|
this.applyInverseSettings(
|
||||||
|
settingsData, dir, otherDir
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.applyTemplateSettings()
|
||||||
|
dialog.close()
|
||||||
|
this.dispatchEvent(new CustomEvent(
|
||||||
|
'settings-change', {bubbles: true, composed: true}
|
||||||
|
))
|
||||||
|
})
|
||||||
|
bGroup.addCancel(this.text.cancel, () => {
|
||||||
|
dialog.close()
|
||||||
|
})
|
||||||
|
dialog.footerEl.appendChild(bGroup)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
applyInverseSettings(settingsData, dir, otherDir) {
|
||||||
|
const selfEntries = Object.entries(
|
||||||
|
settingsData.connections[dir]
|
||||||
|
)
|
||||||
|
for (const [path, access] of selfEntries) {
|
||||||
|
const key = 'settings/page:' + path
|
||||||
|
let val = this.storage.getItem(key)
|
||||||
|
try {
|
||||||
|
if (val !== null) {
|
||||||
|
val = JSON.parse(val)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
const data = val ?? {}
|
||||||
|
data.connections = data.connections ?? {}
|
||||||
|
data.connections[otherDir] = (
|
||||||
|
data.connections[otherDir] ?? {}
|
||||||
|
)
|
||||||
|
data.connections[otherDir][this.path] = access
|
||||||
|
this.storage.setItem(
|
||||||
|
key, JSON.stringify(data)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyInverseRename(
|
||||||
|
settingsData, dir, otherDir, oldPath, newPath
|
||||||
|
) {
|
||||||
|
const selfEntries = Object.entries(
|
||||||
|
settingsData.connections[dir] ?? {}
|
||||||
|
)
|
||||||
|
for (const [path, access] of selfEntries) {
|
||||||
|
const key = 'settings/page:' + path
|
||||||
|
let val = this.storage.getItem(key)
|
||||||
|
try {
|
||||||
|
if (val !== null) {
|
||||||
|
val = JSON.parse(val)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
const data = val ?? {}
|
||||||
|
data.connections = data.connections ?? {}
|
||||||
|
data.connections[otherDir] = (
|
||||||
|
data.connections[otherDir] ?? {}
|
||||||
|
)
|
||||||
|
const accessValue = data.connections[otherDir][oldPath]
|
||||||
|
data.connections[otherDir][newPath] = accessValue
|
||||||
|
data.connections[otherDir][oldPath] = undefined
|
||||||
|
this.storage.setItem(
|
||||||
|
key, JSON.stringify(data)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyTemplateSettings() {
|
||||||
|
const templates = {}
|
||||||
|
for (const key of this.storage.keys()) {
|
||||||
|
try {
|
||||||
|
if (key.startsWith('settings/page:')) {
|
||||||
|
const data = JSON.parse(
|
||||||
|
this.storage.getItem(key)
|
||||||
|
)
|
||||||
|
if (data.template) {
|
||||||
|
const name = key.slice(
|
||||||
|
'settings/page:'.length
|
||||||
|
)
|
||||||
|
templates[name] = {name}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.storage.setItem(
|
||||||
|
'settings:templates',
|
||||||
|
JSON.stringify({templates}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get language() {
|
||||||
|
return this._language
|
||||||
|
}
|
||||||
|
|
||||||
|
set language(language) {
|
||||||
|
this._language = language
|
||||||
|
this.text = this.langEs ? this.textEs : this.textEn
|
||||||
|
}
|
||||||
|
|
||||||
|
get langEs() {
|
||||||
|
return /^es\b/.test(this.language)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue