UNPKG

@silexlabs/silex-dashboard

Version:
488 lines (471 loc) 22.2 kB
--- permalink: "/{{lang}}/" lang: "fr" collection: "Websites" --- <!DOCTYPE html> <html lang=""> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/css/websites-7843a323acc9c4921d373250c5f647854910ea0913530659823fbe29844ee6b5.css" /> <!-- font google --> <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;700&display=swap" rel="stylesheet"> {% render "alternate.liquid" languages: languages lang: lang page: page %} <style> .before-js > * { visibility: hidden; opacity: 0; transition: opacity .5s ease; } .before-js[data-gjs-type] > *, /* This is only inside the editor, .before-js needs to be on the body */ .after-js > * { visibility: visible; opacity: 1; } .before-js:before { content: 'Loading'; position: absolute; top: 49%; left: 49%; } .before-js[data-gjs-type]:before, /* This is only inside the editor, .before-js needs to be on the body */ .after-js:before { content: none; } /*BTNS*/ .button, .pointer { cursor: pointer!important} .button{ min-width:110px; } details { max-height: 2em; display: block; overflow: hidden; transition: max-height .75s ease; } details[open] { max-height: 40em; } /*BTNS*/ a { text-decoration: none; color:#8873FE; } a:hover { text-decoration: underline; } .uppercase { text-transform: uppercase; } .underline:hover{ text-decoration: underline; text-decoration-thickness: from-font; text-underline-position: under; } /*footer position*/ .main-min-height { min-height: calc(100vh - 560px); } /*footer position*/ /*label*/ ::placeholder { color: #8873FE; } input:focus { border: 2px solid #9977FE; background-color:#ffffff; } :focus { outline: none; } /*label*/ .skeleton-anim:after { width: 100%; height: 100%; position: absolute; top: 0; left: 0; content: ""; background: linear-gradient(0.25turn, transparent, rgba(255,255,255,.75), transparent), linear-gradient(transparent, transparent), radial-gradient(38px circle at 19px 19px, transparent 50%, transparent 51%), linear-gradient(transparent, transparent); background-repeat: no-repeat; background-size: 315px 250px, 315px 180px, 100px 100px, 225px 30px; background-position: -315px 0, 0 0, 0px 190px, 50px 195px; animation: loading 1.5s infinite; } @keyframes loading { to { background-position: 200% 0, 0 0, 0 190px, 50px 195px; } } /*FX ANIMATIONS*/ /*scale-round-inside_pour-BTN*/ .fx-scale-round { position:relative; z-index: 10; overflow: hidden; } .fx-scale-round::after { content: ""; background: #ffffff; position: absolute; z-index: -1; border-radius: 50%; left: -50%; right: -50%; top: -100%; bottom: -100%; transform: scale(0, 0); transform-origin: center bottom; transition: all 0.3s ease-out; } .fx-scale-round:hover { transform-origin: center bottom; transform: scale(1.1); transition: transform 0.2s cubic-bezier(0, -0.530, 0.405, 2.8); } .fx-scale-round:hover::after { transform: scale(1, 1); transition: transform 0.2s cubic-bezier(0, -0.530, 0.405, 2.8); } /*scale-round-inside_pour-BTN*/ /*scale*/ .fx-scale:hover { transform-origin: center bottom; transform: scale(1.1); transition: transform 0.2s cubic-bezier(0, -0.530, 0.405, 2.8); } /*flash*/ .fx-flash:hover { animation: flash-in .25s ; } /*flash-in animation*/ @keyframes flash-in{ 0% { opacity:.25; } 100% { opacity:1; } } /*flash-in animation*/ /*FX ANIMATIONS*/ </style> <script src="/js/vue.global.prod.js"></script> <script src="/js/main.js"></script> <script type="module"> const CONNECTORS_PATH = '/connectors/' window.addEventListener('load', function() { const { createApp } = Vue; const { api, constants, types } = silex; const { ConnectorType, } = types const { setServerUrl, getUser, logout, websiteDelete, websiteDuplicate, websiteList, websiteCreate, websiteMetaWrite, } = api function toSafeId(name) { return name.replace(/[/\\?%*:|"<>]/g, '_') } const App = { data() { return { websites: [], newWebsiteName: '', showCreationForm: false, error: null, message: null, loggedIn: false, loading: true, storage: null, user: null, showMenu: false, empty: false, } }, mounted() { this.init() }, methods: { async init() { try { // Init Silex server path // Go up one level because of the language prefix setServerUrl(window.location.origin) // Start const user = await getUser({type: ConnectorType.STORAGE}) // Escape single quotes in the picture URL and decode the picture URL if(user) { user.picture = decodeURIComponent(user.picture).replace(/'/g, "\\'") this.user = user this.loggedIn = true this.websites = await websiteList({connectorId: this.user.storage.connectorId}) this.empty = this.websites.length === 0 this.loading = false } else { this.openLogin() } } catch (error) { console.error(error) this.loading = false if(error.code === 401 || error.httpStatusCode === 401) { this.loggedIn = false this.openLogin() } else { this.error = `{{ api-translations[lang]["Failed to start dashboard"] }} - ${error.message}` this.message = '' } } }, openLogin() { //throw new Error('debug') const path = `/{{lang}}${CONNECTORS_PATH}` console.log(window.location.pathname, window.location.path, path) if(window.location.pathname === path) return window.open(path, '_self') }, openEditor(id) { window.open(`/?id=${id}&lang={{lang}}&connectorId=${this.user.storage.connectorId}`, '_self') }, async logout() { await logout({ type: ConnectorType.STORAGE, connectorId: this.user.storage.connectorId, }) window.location.reload() }, async createWebsite() { try { if (!this.newWebsiteName) throw new Error('{{ api-translations[lang]["You need to provide a website name"] }}') this.loading = true const websiteId = toSafeId(this.newWebsiteName) const result = await websiteCreate({ websiteId, data: { name: this.newWebsiteName, imageUrl: null, }, connectorId: this.user.storage.connectorId }) this.message = '{{ api-translations[lang]["Website created successfully"] }}' this.error = '' this.newWebsiteName = '' this.showCreationForm = false; this.websites = await websiteList({connectorId: this.user.storage.connectorId}) this.empty = this.websites.length === 0 this.loading = false return result } catch (error) { this.loading = false console.error(error) this.error = `{{ api-translations[lang]["Failed to create website"] }} - ${error.message}` this.message = '' } }, async deleteWebsite(websiteId) { const ok = confirm('{{ api-translations[lang]["Deleting a website? Are your sure? Really?"] }}') if (!ok) return this.loading = true try { const result = await websiteDelete({websiteId, connectorId: this.user.storage.connectorId}) this.message = '{{ api-translations[lang]["Website deleted successfully"] }}' this.error = '' this.websites = await websiteList({connectorId: this.user.storage.connectorId}) this.empty = this.websites.length === 0 this.loading = false return result } catch (error) { this.loading = false this.error = `{{ api-translations[lang]["Failed to delete website"] }} - ${error.message}` this.message = '' } }, async duplicateWebsite(websiteId) { this.loading = true try { await websiteDuplicate({websiteId, connectorId: this.user.storage.connectorId, data: { name }}) this.error = '' this.websites = await websiteList({connectorId: this.user.storage.connectorId}) this.message = '{{ api-translations[lang]["Website duplicated successfully"] }}' this.empty = this.websites.length === 0 this.loading = false } catch (error) { this.loading = false this.error = `{{ api-translations[lang]["Failed to duplicate website"] }} - ${error.message}` this.message = '' } }, async renameWebsite(websiteId) { const website = this.websites.find(w => w.websiteId === websiteId) const name = prompt('{{ api-translations[lang]["New name for this website"] }}', website.name) if (!name) return this.loading = true try { const result = await websiteMetaWrite({websiteId, connectorId: this.user.storage.connectorId, data: { name }}) this.message = '{{ api-translations[lang]["Website renamed successfully"] }}' this.error = '' this.websites = await websiteList({connectorId: this.user.storage.connectorId}) this.empty = this.websites.length === 0 this.loading = false return result } catch (error) { this.loading = false this.error = `{{ api-translations[lang]["Failed to rename website"] }} - ${error.message}` this.message = '' } }, }, }; // Prepare elements for vue document.querySelectorAll('[v-text], [v-html]') .forEach(el => el.innerText = '') // Create the app const app = createApp(App); // Mount the app app.mount('.app'); // Remove loading setTimeout(() => { document.querySelector('.before-js').classList.add('after-js') }, 100) }) </script> <title>{% liquid assign var_ik0i_39 = tina.homeConnection.edges | where: "", | first assign var_ik0i_40 = var_ik0i_39.node.title echo var_ik0i_40 %}</title> <link rel="icon" href="/assets/favicon-32x32.png" /> <meta name="og:title" property="og:title" content="Silex Dashboard"/> <link href="https://fonts.googleapis.com" rel="preconnect" ><link href="https://fonts.gstatic.com" rel="preconnect" crossorigin ><link href="https://fonts.googleapis.com/css?family=Ubuntu&display=swap" rel="stylesheet" ></head> {% liquid assign var_ik0i_36 = tina.settingsConnection.edges | where: "node.lang", page.lang | first assign state_ik0i-958_ik0i-e8l061o7k5 = var_ik0i_36 %} {% liquid assign var_ik0i_37 = tina.homeConnection.edges | where: "node.lang", page.lang | first assign var_ik0i_38 = var_ik0i_37.node assign state_ik0i-958_ik0i-24xejc2n0xy = var_ik0i_38 %}<body id="ik0i" class="body loading app before-js"><HEADER id="igrg" class="menu-bar"><A id="igvu43" href="/"><img src="/assets/picto-silex@3x.png" id="iel80b-2-2" class="nav__logo"/></A><NAV id="i9jq" class="nav">{% liquid assign var_iels_1 = tina.settingsConnection.edges | where: "node.lang", page.lang | first assign var_iels_2 = var_iels_1.node.nav %} {% for state_iels-228___data in var_iels_2 %} <a id="iels" href="{% liquid assign var_iels_3 = state_iels-228___data.url echo var_iels_3 %}" class="nav__item uppercase fx-flash nav_item--active" target="{% liquid assign var_iels_4 = state_iels-228___data.target echo var_iels_4 %}">{% liquid assign var_iels_0 = state_iels-228___data.label echo var_iels_0 %}</a>{% endfor %}</NAV>{% liquid assign var_i2red7_7 = tina.languagesConnection.edges %} {% for state_i2red7-8291___data in var_i2red7_7 %} <div id="i2red7" class="lang"><a href="{% liquid assign var_iciz_6 = state_i2red7-8291___data.node.permalink echo var_iciz_6 %}" id="iciz" class="lang__item nav__item uppercase">{% liquid assign var_iciz_5 = state_i2red7-8291___data.node.label echo var_iciz_5 %}</a></div>{% endfor %}<div id="i24ew" class="user__wrapper pointer" v-if="user" v-on:click="showMenu = !showMenu"><div id="i5xsbd" class="user-icon__wrapper" v-if="user" v-show="!showMenu || user.storage.disableLogout"><div id="i5wlbq" class="user-icon__image" v-if="user" v-show="!showMenu || user.storage.disableLogout" :style="{ backgroundImage: `url('${user?.picture}')`, backgroundRepeat: 'no-repeat', backgroundSize: 'contain', }"></div></div><div id="ic9eoa" class="" v-show="showMenu && !user.storage.disableLogout" v-on:click="logout"><div id="igv1rf" class="nav__item">Logout</div></div></div></HEADER><HEADER id="iy8ax3" class="bg-silex-purpel"><div id="iisz8f" class="section-top text-centered text-white"><h1 id="ic31o" class="title-40" v-if="!empty">{% liquid assign var_ic31o_8 = state_ik0i-958_ik0i-24xejc2n0xy.title2 echo var_ic31o_8 %}</h1><p id="iyex8" class="subtitle-16" v-if="!empty">{% liquid assign var_iyex8_9 = state_ik0i-958_ik0i-24xejc2n0xy.subtitle echo var_iyex8_9 %}</p><h1 id="i4ybc" class="title-40" v-if="empty">{% liquid assign var_i4ybc_10 = state_ik0i-958_ik0i-24xejc2n0xy.title2_empty echo var_i4ybc_10 %}</h1><p id="iino6r" class="subtitle-16" v-if="empty">{% liquid assign var_iino6r_11 = state_ik0i-958_ik0i-24xejc2n0xy.subtitle_empty echo var_iino6r_11 %}</p></div></HEADER><MAIN id="iz63r" class="padding-normal main-min-height website-max-width margin-80"><section id="iqmx38" class="" v-if="empty"></section><div id="ickx4" class="margin-20" v-if="!empty"><button id="ic92g" class="button button--primary rounded top-space-40 fx-scale-round" v-if="!showCreationForm" v-on:click="showCreationForm = !showCreationForm"><span id="igsxoc" class="icon-font">+</span> <span id="ixu14" class="">{% liquid assign var_ixu14_12 = state_ik0i-958_ik0i-24xejc2n0xy.add_button echo var_ixu14_12 %}</span></button><div id="i0ro3" class="button button--secondary rounded">Import</div></div><div id="ihwwxz" class="box top-space-40 padding-30 box_transp" v-if="showCreationForm"><h3 id="i3gd1b" class="box__header text-centered">{% liquid assign var_i3gd1b_13 = state_ik0i-958_ik0i-24xejc2n0xy.add_title echo var_i3gd1b_13 %}</h3><form method="get" id="i50acf" class="form" v-on:submit.prevent="createWebsite"><div id="igtg1t" class="v-space"><label id="i1nmbc" style="flex-shrink:0;" class="v-space bold color-2B1B63-80">{% liquid assign var_i1nmbc_14 = state_ik0i-958_ik0i-24xejc2n0xy.add_name_label echo var_i1nmbc_14 %}</label><input type="text" id="ij5iwh" placeholder="{% liquid assign var_ij5iwh_15 = state_ik0i-958_ik0i-24xejc2n0xy.add_name_placeholder echo var_ij5iwh_15 %}" class="input full-width" v-model="newWebsiteName"></input></div><div id="ie0xes"><button type="submit" id="i021na" class="button rounded button--primary right-space-20 fx-scale-round">{% liquid assign var_i021na_16 = state_ik0i-958_ik0i-24xejc2n0xy.add_ok echo var_i021na_16 %}</button><button type="reset" class="button rounded button--secondary fx-scale-round" v-on:click="showCreationForm = !showCreationForm" v-if="!empty">{% liquid assign var_irmaf_17 = state_ik0i-958_ik0i-24xejc2n0xy.add_cancel echo var_irmaf_17 %}</button></div></form></div><div id="if80m" class="margin-20"><section id="idgvg" class="button-bar loaded__item" v-if="!loading" v-for="(website, index) in websites" :key="index"><h3 id="i69a7" class="right-space-40 color-2B1B63-80 uppercase pointer fx-flash full-width button-bar__title underline" v-on:click="openEditor(website.websiteId)" v-text="website.name || website.id">My first website</h3><p id="i65hn" class="button-bar__item--secondary flex-no-shrink right-space-40" v-text="'Updated ' + new Date(website.updatedAt).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })">Updated 1h ago by lexoyo</p><p id="i64qa" class="button-bar__item--secondary flex-no-shrink right-space-40" v-text="'Created ' + new Date(website.createdAt).toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })">Created 2023-02-16 by lexoyo</p><div id="i3b4tr" class="flex-no-shrink"><button id="ifyf6p" title="{% liquid assign var_ifyf6p_19 = state_ik0i-958_ik0i-24xejc2n0xy.list_edit echo var_ifyf6p_19 %}" class="button-bar__item--link pointer fx-scale fx-flash button-bar__item--icon" v-on:click="openEditor(website.websiteId)">{% liquid assign var_ifyf6p_18 = state_ik0i-958_ik0i-24xejc2n0xy.list_edit_icon echo var_ifyf6p_18 %}</button><button id="ihf6ew" title="{% liquid assign var_ihf6ew_21 = state_ik0i-958_ik0i-24xejc2n0xy.list_rename echo var_ihf6ew_21 %}" class="button-bar__item--link pointer fx-scale fx-flash button-bar__item--icon" v-on:click="renameWebsite(website.websiteId)">{% liquid assign var_ihf6ew_20 = state_ik0i-958_ik0i-24xejc2n0xy.list_rename_icon echo var_ihf6ew_20 %}</button><button id="iol4h" title="{% liquid assign var_iol4h_23 = state_ik0i-958_ik0i-24xejc2n0xy.list_duplicate echo var_iol4h_23 %}" class="button-bar__item--link pointer fx-flash fx-scale button-bar__item--icon" v-on:click="duplicateWebsite(website.websiteId)">{% liquid assign var_iol4h_22 = state_ik0i-958_ik0i-24xejc2n0xy.list_duplicate_icon echo var_iol4h_22 %}</button><button id="it5ia" class="button-bar__item--link pointer fx-flash fx-scale" title="{% liquid assign var_it5ia_24 = state_ik0i-958_ik0i-24xejc2n0xy.list_delete echo var_it5ia_24 %}" v-on:click="deleteWebsite(website.websiteId)">X</button></div></section><section id="i1fjn" class="button-bar loading__item skeleton-anim skeleton-wrapper" v-if="loading"><H3 id="iwu6a" class="skeleton-text skeleton right-space-40">My first websiteMy first websiteMy first websiteMy first</H3><P id="i26fn" class="button-bar__item--secondary skeleton-text skeleton right-space-40">Updated 1h ago by lexoyo</P><P id="iywbk" class="button-bar__item--secondary skeleton-text skeleton right-space-40">Created 2023-02-16 by lexoyo</P><div id="ixz6c" class="skeleton skeleton-button">Edit</div></section><section id="iwxxo5" class="button-bar loading__item skeleton-anim skeleton-wrapper" v-if="loading"><H3 id="inmp3" class="skeleton-text skeleton right-space-40">My first websiteMy first websiteMy first websiteMy first</H3><P id="icjz8" class="button-bar__item--secondary skeleton-text skeleton right-space-40">Updated 1h ago by lexoyo</P><P id="illbe" class="button-bar__item--secondary skeleton-text skeleton right-space-40">Created 2023-02-16 by lexoyo</P><div id="i9fx3l" class="skeleton skeleton-button">Edit</div></section><section id="isld3r" class="button-bar loading__item skeleton-anim skeleton-wrapper" v-if="loading"><H3 class="button-bar_item button-bar__item--main skeleton-text skeleton right-space-40">My first websiteMy first websiteMy first websiteMy first</H3><P class="button-bar_item button-bar__item--secondary skeleton-text skeleton right-space-40">Updated 1h ago by lexoyo</P><P class="button-bar_item button-bar__item--secondary skeleton-text skeleton right-space-40">Created 2023-02-16 by lexoyo</P><div id="i8oes3" class="button-bar_item skeleton skeleton-button">Edit</div></section></div><div id="ipccl7"><div id="i2fkm9" class="margin-20 empty-image" v-if="empty"></div><div id="i5ydxo" class="box padding-50-30 box--centered" v-if="empty"><p id="ikl1qu" class="text-centered title-26">{% liquid assign var_ikl1qu_25 = state_ik0i-958_ik0i-24xejc2n0xy.text_empty1 echo var_ikl1qu_25 %}</p><h3 id="iwzrqi" class="text-centered title-26">{% liquid assign var_iwzrqi_26 = state_ik0i-958_ik0i-24xejc2n0xy.text_empty2 echo var_iwzrqi_26 %}</h3><button id="i2x0l" class="button button--primary rounded top-space-40 fx-scale-round" v-on:click="showCreationForm = !showCreationForm" v-if="!showCreationForm"><span id="ibsgw" class="icon-font">+</span> <span id="itl2n8" class="">{% liquid assign var_itl2n8_27 = state_ik0i-958_ik0i-24xejc2n0xy.add_button echo var_itl2n8_27 %}</span></button></div></div><div id="i7ej6j" class="flex-between box-message text-white" v-if="error"><h3 id="iv0eyi" class="box-message-text" v-text="error">Insert your text here</h3><div id="i4656n" class="pointer button-bar__item--link text-white" v-on:click="error = null">{% liquid assign var_i4656n_28 = state_ik0i-958_ik0i-24xejc2n0xy.message_dismiss echo var_i4656n_28 %}</div></div><div id="ilteie" class="flex-between box-message text-white" v-if="message"><h3 id="i2d31v" class="box-message-text" v-text="message">Insert your text here</h3><div id="i2urco" class="rounded pointer button-bar__item--link text-white" v-on:click="message = null">{% liquid assign var_i2urco_29 = state_ik0i-958_ik0i-24xejc2n0xy.message_dismiss echo var_i2urco_29 %}</div></div></MAIN><FOOTER id="ilzpl" class="footer">{% liquid assign var_isucae_35 = state_ik0i-958_ik0i-e8l061o7k5.node.footer_links %} {% for state_isucae-3308___data in var_isucae_35 %} <div id="isucae" style="min-height:100px;" class="footer__column"><h3 id="ipa5zg" href="" class="footer__item">{% liquid assign var_ipa5zg_30 = state_isucae-3308___data.title echo var_ipa5zg_30 %}</h3>{% liquid assign var_irs6gh_32 = state_isucae-3308___data.columns %} {% for state_i2u9h4-2642___data in var_irs6gh_32 %} <a href="{% liquid assign var_irs6gh_33 = state_i2u9h4-2642___data.url echo var_irs6gh_33 %}" class="footer__item" target="{% liquid assign var_irs6gh_34 = state_i2u9h4-2642___data.target echo var_irs6gh_34 %}">{% liquid assign var_irs6gh_31 = state_i2u9h4-2642___data.label echo var_irs6gh_31 %}</a>{% endfor %}</div>{% endfor %}</FOOTER></body> </html>