Files
phptimerboard2/vendor/facade/ignition/resources/js/components/Solutions/SolutionCard.vue
2019-09-29 19:47:00 -05:00

238 lines
8.2 KiB
Vue

<template>
<div>
<div
class="solution-toggle"
@click="toggleSolutions"
:class="{
'solution-toggle-show': isHidingSolutions,
}"
>
<a v-if="isHidingSolutions" class="link-solution" target="_blank"
><i class="far fa-lightbulb text-xs mr-1"></i> Show solutions</a
>
<a v-else class="link-solution" target="_blank">Hide solutions</a>
</div>
<div
ref="solutionCard"
class="solution"
:class="{
'solution-hidden': isHidingSolutions,
}"
>
<div class="solution-main">
<div class="solution-background mx-0">
<svg
class="hidden absolute right-0 h-full | md:block"
x="0px"
y="0px"
viewBox="0 0 299 452"
>
<g style="opacity: 0.075">
<polygon
style="fill:rgb(63,63,63)"
points="298.1,451.9 150.9,451.9 21,226.9 298.1,227.1"
/>
<polygon
style="fill:rgb(151,151,151)"
points="298.1,227.1 21,226.9 150.9,1.9 298.1,1.9"
/>
</g>
</svg>
</div>
<div class="p-12">
<div class="solution-content ml-0">
<h2 class="solution-title">{{ solution.title }}</h2>
<div
v-if="solution.description"
v-html="markdown(solution.description)"
></div>
<div v-if="solution.is_runnable">
<p v-html="markdown(solution.action_description)"></p>
<p v-if="canExecuteSolutions === null" class="py-4 text-sm italic">
Loading...
</p>
<div class="mt-4">
<button
v-if="
solution.is_runnable &&
canExecuteSolutions === true &&
executionSuccessful === null
"
@click="execute"
class="button-secondary button-lg bg-tint-300 hover:bg-tint-400"
>
{{ solution.run_button_text }}
</button>
<p v-if="executionSuccessful">
<strong class="font-semibold"
>The solution was executed succesfully.</strong
>
<a href="#" @click.prevent="refresh" class="link-solution"
>Refresh now.</a
>
</p>
<p v-if="executionSuccessful === false">
Something went wrong when executing the solution. Please try
refresh the page and try again.
</p>
</div>
</div>
<div
class="mt-8 grid justify-start"
v-if="Object.entries(solution.links).length > 0"
>
<div class="border-t-2 border-gray-700 opacity-25 " />
<div class="pt-2 grid cols-auto-1fr gapx-4 gapy-2 text-sm">
<label class="font-semibold uppercase tracking-wider"
>Read more</label
>
<ul>
<li v-for="(link, label) in solution.links" :key="label">
<a :href="link" class="link-solution" target="_blank">{{
label
}}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
const MarkdownIt = require('markdown-it')();
const cookieName = 'hide_solutions';
let animationTimeout = null;
export default {
inject: ['config'],
props: {
solution: { required: true },
},
data() {
return {
isHidingSolutions: this.hasHideSolutionsCookie(),
canExecuteSolutions: null,
executionSuccessful: null,
};
},
computed: {
healthCheckEndpoint() {
return this.solution.execute_endpoint.replace('execute-solution', 'health-check');
},
},
created() {
this.configureRunnableSolutions();
},
mounted() {
if (this.isHidingSolutions) {
this.$refs.solutionCard.classList.add('solution-hidden');
}
},
methods: {
configureRunnableSolutions() {
if (!this.config.enableRunnableSolutions) {
this.canExecuteSolutions = false;
return;
}
this.checkExecutionEndpoint();
},
markdown(string) {
return MarkdownIt.render(string);
},
async checkExecutionEndpoint() {
try {
const healthCheck = await (await fetch(this.healthCheckEndpoint)).json();
this.canExecuteSolutions = healthCheck.can_execute_commands;
} catch (error) {
this.canExecuteSolutions = false;
}
},
async execute() {
try {
const response = await fetch(this.solution.execute_endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
solution: this.solution.class,
parameters: this.solution.run_parameters,
}),
});
this.executionSuccessful = response.status === 200;
} catch (error) {
console.error(error);
this.executionSuccessful = false;
}
},
refresh() {
location.reload();
},
getUrlLabel(url) {
const tempElement = document.createElement('a');
tempElement.href = url;
return tempElement.hostname;
},
toggleSolutions() {
if (!this.isHidingSolutions) {
this.$refs.solutionCard.classList.add('solution-hiding');
animationTimeout = window.setTimeout(() => {
this.$refs.solutionCard.classList.remove('solution-hiding');
this.toggleHidingSolutions();
}, 100);
} else {
window.clearTimeout(animationTimeout);
this.toggleHidingSolutions();
}
},
toggleHidingSolutions() {
if (this.isHidingSolutions) {
document.cookie = `${cookieName}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;`;
this.isHidingSolutions = false;
return;
}
const expires = new Date();
expires.setTime(expires.getTime() + 365 * 24 * 60 * 60 * 1000);
document.cookie = `${cookieName}=true;expires=${expires.toUTCString()};path=/;`;
this.isHidingSolutions = true;
},
hasHideSolutionsCookie() {
return document.cookie.includes(cookieName);
},
},
};
</script>