Skip to content

Commit

Permalink
Dev (#34)
Browse files Browse the repository at this point in the history
* Synchronizing code from bitbucket repository

* Removing TomSelect because it is no longer updated

* Metric template remove restriction

* Multiple environment variables fix

* - Setting dark mode by default in the login window
- Providing better view of current build id and build environment for debugging
- Added environment variables to set_env.sh so that they can be set during build

* Application saving and traversing through the ui fixed #8 #11

* Fixing ts errors on Error handling

* Adding build specific information for better debugging

* Added new button to duplicate application

* Bug fixes and improvements

* Added undeploy functionality

---------

Co-authored-by: Fotis Paraskevopoulos <[email protected]>
  • Loading branch information
vkefalas-exz and fotisp authored Oct 4, 2024
1 parent 7554942 commit 8be9ca7
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 45 deletions.
101 changes: 64 additions & 37 deletions gui/src/containers/Applications/Overview/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@
<div class="flex items-center justify-between">
<div class="block">
<p
class="text-3xl capitalize hover:underline hover:cursor-pointer inline-block align-middle"
@click="toApplicationEditing(application)"
class="text-3xl capitalize hover:underline hover:cursor-pointer inline-block align-middle"
@click="toApplicationEditing(application)"
>
{{ application.title }}
</p>
<p class="cursor-pointer rounded-full px-2 py-2 mx-2 text-xs font-medium text-white inline-block"
:class="application.status == 'draft' ? 'bg-gray-700' :
:class="application.status == 'draft' ? 'bg-gray-700' :
application.status == 'deploying' ? 'bg-primary' :
application.status == 'ready' ? 'bg-success' :
application.status =='deployed' ? 'bg-purple-900' : ''"
v-if="application.status">
application.status =='deployed' ? 'bg-success' :
application.status =='undeploying' ? 'bg-red-400' : ''"
v-if="application.status">
{{application.status}}
</p>
<p class="cursor-pointer rounded-full px-2 py-2 mx-2 text-xs dark:bg-darkmode-800 font-medium text-white inline-block"
v-if="!application.status">
v-if="!application.status">
unknown
</p>

</div>
<div class="flex space-x-2">

<Lucide icon="PlayCircle" class="w-10 text-white" @click="deployApplication(application)" />
<Lucide v-if="application.status=='draft' || application.status=='ready' || application.status=='deploying'|| !application.status" icon="PlayCircle" class="w-10 text-white" @click="deployApplication(application)" />
<Lucide v-if="application.status=='draft' || application.status=='ready' || !application.status" icon="Pencil" class="w-10 text-warning" @click="toApplicationEditing(application)" />
<Lucide v-if="application.status=='draft' || application.status=='ready' || !application.status" icon="Copy" class="w-10 text-info" @click="duplicateApplication(application)" />
<Lucide v-if="application.status == 'deployed' || application.status == 'ready' || !application.status" icon="Unlock" class="w-10 text-alert" @click="undeployApplication(application)" />
<Lucide v-if="application.status" icon="Copy" class="w-10 text-info" @click="duplicateApplication(application)" />
<Lucide v-if="application.status=='draft' || application.status=='ready' || !application.status" icon="Trash2" class="w-10 text-danger" @click="removeApplication(application.uuid)" />
</div>
</div>
Expand All @@ -43,11 +43,11 @@
<h2 class="text-2xl">{{ application.latency || 0 }} MS</h2>
</div>
<BaseChart
v-if="application.latency"
type="line"
:height="120"
:width="180"
:data="latencyLineChartConfig(application.latency)"
v-if="application.latency"
type="line"
:height="120"
:width="180"
:data="latencyLineChartConfig(application.latency)"
/>
</Card>
<!-- END: LATENCY -->
Expand All @@ -58,11 +58,11 @@
<h2 class="text-2xl">{{ application.reconfigurations || 0 }}</h2>
</div>
<BaseChart
v-if="application.reconfigurations"
type="bar"
:height="120"
:width="180"
:data="reconfigDiagramConfig(application.reconfigurations)"
v-if="application.reconfigurations"
type="bar"
:height="120"
:width="180"
:data="reconfigDiagramConfig(application.reconfigurations)"
/>
</Card>
<!-- END: RECONFIGURATION -->
Expand All @@ -74,11 +74,11 @@
</div>

<BaseChart
v-if="application.deployments"
type="bar"
:height="120"
:width="180"
:data="deploymentsDiagramConfig(application.deployments)"
v-if="application.deployments"
type="bar"
:height="120"
:width="180"
:data="deploymentsDiagramConfig(application.deployments)"
/>
</Card>
<!-- END: DEPLOYMENTS -->
Expand All @@ -90,11 +90,11 @@
</div>

<BaseChart
v-if="application.violations"
type="line"
:height="120"
:width="180"
:data="violationsLineChartConfig(application.violations)"
v-if="application.violations"
type="line"
:height="120"
:width="180"
:data="violationsLineChartConfig(application.violations)"
/>
</Card>
<!-- END: SLO VIOLATIONS -->
Expand All @@ -113,7 +113,7 @@
</template>

<script setup lang="ts">
import { computed } from "vue"
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { useRouter } from "vue-router"
import { useApplicationStore } from "@/store/modules/application.ts"
import { useUIStore } from "@/store/modules/ui.ts"
Expand All @@ -137,11 +137,6 @@ const uiStore = useUIStore()
const applications = computed<Array<IApplicationOverview>>(() => applicationStore.applications.results)
const retrieveApplications = () => {
applicationStore.getAllApplications()
}
retrieveApplications()
const redirectToAppCreation = () => {
router.push({ name: "application-creation" })
Expand Down Expand Up @@ -195,4 +190,36 @@ const duplicateApplication = (application: IApplication) => {
}
})
}
</script>
const undeployApplication = (application: IApplication) => {
applicationStore.undeployApplication(application.uuid).then(() => {
application.status = "undeploying";
applicationStore.startPolling();
uiStore.setSnackbarMessage({
message: `You need to manually undeploy resources.`,
type: SNACKBAR_MESSAGE_TYPES.INFO
});
applicationStore.startPolling();
}).catch(() => {
uiStore.setSnackbarMessage({
message: `Failed to undeploy application ${application.title}`,
type: SNACKBAR_MESSAGE_TYPES.ERROR
});
});
};
onMounted(() => {
// Retrieve applications and then start polling
applicationStore.getAllApplications().then(() => {
applicationStore.startPolling();
});
});
onBeforeUnmount(() => {
applicationStore.stopPolling();
});
</script>
12 changes: 8 additions & 4 deletions gui/src/store/api-services/application.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ export default {
},
async duplicateApplication(uuid: string): Promise<IApplicationOverview> {
return axios.post(`/api/v1/application/${uuid}/uuid/duplicate`).then(({data}) => data)
}


}
},
async undeployApplication(uuid: string): Promise<DeployResponseType> {
return axios.post(`/api/v1/application/${uuid}/uuid/undeploy`).then(({data}) => data)
},
async checkApplicationStatus(uuids: string[]): Promise<Array<{ uuid: string; status: string }>> {
return axios.post("/api/v1/application/status", { uuids }).then(({ data }) => data)
},
}
93 changes: 89 additions & 4 deletions gui/src/store/modules/application.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { defineStore } from "pinia"
import applicationService from "@/store/api-services/application.service.ts"
import { IApplication, IApplicationOverview } from "@/interfaces/application.interface.ts"
import { useUIStore } from "@/store/modules/ui.ts"; // Import the UI store
import { SNACKBAR_MESSAGE_TYPES } from "@/constants";

interface ApplicationState {
applications: IPagination<IApplicationOverview>
pollingTimerId?: number;
}

export const useApplicationStore = defineStore("application", {
state: (): ApplicationState => ({
applications: { pages: 0, currentPage: 0, results: [] }
applications: { pages: 0, currentPage: 0, results: [] },
pollingTimerId: undefined,
}),
actions: {
async validateApplication(payload: Partial<IApplication>): Promise<boolean> {
Expand Down Expand Up @@ -63,6 +67,87 @@ export const useApplicationStore = defineStore("application", {
const duplicatedApplication: IApplicationOverview = await applicationService.duplicateApplication(uuid)
this.applications.results.unshift(duplicatedApplication)
return duplicatedApplication
}
}
})
},
async undeployApplication(uuid: string): Promise<string> {
return applicationService.undeployApplication(uuid).then((status) => {
const app: any = this.applications.results.find((app) => app.uuid === uuid);
app.status = status.status;
return status.status;
});
},

async checkApplicationStatus(uuids: string[]): Promise<void> {
console.log("Checking status for applications:", uuids);

const response = await applicationService.checkApplicationStatus(uuids);
console.log("Received status updates:", response);

response.forEach((updatedApp) => {
const appIndex = this.applications.results.findIndex((app) => app.uuid === updatedApp.uuid);
if (appIndex !== -1) {
const app = this.applications.results[appIndex];
const previousStatus = app.status;
app.status = updatedApp.status;

if (previousStatus !== "draft" && updatedApp.status === "draft") {
const uiStore = useUIStore();
uiStore.setSnackbarMessage({
message: `Application ${app.title} has been unlocked successfully`,
type: SNACKBAR_MESSAGE_TYPES.SUCCESS,
});
}

console.log(`Updated application ${updatedApp.uuid} to status ${updatedApp.status}`);
}
});
},

startPolling() {
console.log("Polling started...");

const batchSize = 100;
let interval = 10000; //10 sec
//const maxInterval = 60000;

const pollStatus = async () => {
const deployingApps = this.applications.results.filter(
(app) => app.status === "deploying" || app.status === "undeploying"
);

if (deployingApps.length === 0) {
console.log("No applications to poll for.");
return;
}

console.log(`Polling for ${deployingApps.length} deploying/undeploying applications.`);

for (let i = 0; i < deployingApps.length; i += batchSize) {
const batch = deployingApps.slice(i, i + batchSize);
await this.checkApplicationStatus(batch.map((app) => app.uuid));
}

const stillDeploying = this.applications.results.some(
(app) => app.status === "deploying" || app.status === "undeploying"
);

if (stillDeploying) {
console.log(`Some applications are still deploying. Polling again.`);
this.pollingTimerId = window.setTimeout(pollStatus, interval);
} else {
console.log("All applications have completed. Stopping polling.");
this.stopPolling();
}
};

pollStatus();
},

stopPolling() {
if (this.pollingTimerId) {
clearTimeout(this.pollingTimerId);
this.pollingTimerId = undefined;
console.log("Polling stopped.");
}
},
},
});

0 comments on commit 8be9ca7

Please sign in to comment.