diff --git a/structures-frontend-next/components.d.ts b/structures-frontend-next/components.d.ts index 992413a82..de52b8b4a 100644 --- a/structures-frontend-next/components.d.ts +++ b/structures-frontend-next/components.d.ts @@ -22,6 +22,7 @@ declare module 'vue' { CrudTable: typeof import('./src/components/CrudTable.vue')['default'] DashboardWidgetCard: typeof import('./src/components/DashboardWidgetCard.vue')['default'] DataTable: typeof import('primevue/datatable')['default'] + Dialog: typeof import('primevue/dialog')['default'] EmptyState: typeof import('./src/components/EmptyState.vue')['default'] EnumNode: typeof import('./src/components/nodes/EnumNode.vue')['default'] ERTable: typeof import('./src/components/modals/ERTable.vue')['default'] @@ -34,6 +35,7 @@ declare module 'vue' { Menu: typeof import('primevue/menu')['default'] NewProjectSidebar: typeof import('./src/components/NewProjectSidebar.vue')['default'] ObjectNode: typeof import('./src/components/nodes/ObjectNode.vue')['default'] + OpenAPIModal: typeof import('./src/components/modals/OpenAPIModal.vue')['default'] Paginator: typeof import('primevue/paginator')['default'] Password: typeof import('primevue/password')['default'] Popover: typeof import('primevue/popover')['default'] diff --git a/structures-frontend-next/public/scalar-ui.html b/structures-frontend-next/public/scalar-ui.html index 791f3a8e0..f0e5cb46b 100644 --- a/structures-frontend-next/public/scalar-ui.html +++ b/structures-frontend-next/public/scalar-ui.html @@ -13,10 +13,7 @@ - - - diff --git a/structures-frontend-next/src/assets/login-page-logo-new.svg b/structures-frontend-next/src/assets/login-page-logo-new.svg new file mode 100644 index 000000000..d9c747c9b --- /dev/null +++ b/structures-frontend-next/src/assets/login-page-logo-new.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/structures-frontend-next/src/assets/login-page-symbol-new.svg b/structures-frontend-next/src/assets/login-page-symbol-new.svg new file mode 100644 index 000000000..08a15de81 --- /dev/null +++ b/structures-frontend-next/src/assets/login-page-symbol-new.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/structures-frontend-next/src/assets/login-page-symbol.svg b/structures-frontend-next/src/assets/login-page-symbol.svg new file mode 100644 index 000000000..08a15de81 --- /dev/null +++ b/structures-frontend-next/src/assets/login-page-symbol.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/structures-frontend-next/src/assets/mcp.svg b/structures-frontend-next/src/assets/mcp.svg new file mode 100644 index 000000000..ba9ec2547 --- /dev/null +++ b/structures-frontend-next/src/assets/mcp.svg @@ -0,0 +1,4 @@ + + + + diff --git a/structures-frontend-next/src/components/CrudTable.vue b/structures-frontend-next/src/components/CrudTable.vue index 2647d60b0..a71c72440 100644 --- a/structures-frontend-next/src/components/CrudTable.vue +++ b/structures-frontend-next/src/components/CrudTable.vue @@ -60,7 +60,8 @@ class CrudTable extends Vue { @Prop({ default: 'No items yet' }) emptyStateText!: string @Prop({ default: '' }) search!: string @Prop({ default: true }) showPagination!: boolean - @Prop({ default: true }) enableRowHover!: boolean; + @Prop({ default: true }) enableRowHover!: boolean + @Prop({ default: 10 }) defaultPageSize!: number getRowClass() { return { @@ -78,7 +79,7 @@ class CrudTable extends Vue { searchText: string | null = ""; options = { page: 0, - rows: 9, + rows: 10, first: 0, sortField: "", sortOrder: 1 as 1 | -1, @@ -108,10 +109,22 @@ class CrudTable extends Vue { return this.enableViewSwitcher && this.activeView === "column"; } + get paginationOptions(): number[] { + const options = [5, 10, 20, 50]; + if (!options.includes(this.defaultPageSize)) { + options.push(this.defaultPageSize); + options.sort((a, b) => a - b); + } + return options; + } + mounted() { const urlSearch = (this.$route.query.search as string) || '' this.loading = true - this.initialSearchCompleted = false + this.initialSearchCompleted = false + + this.options.rows = this.defaultPageSize; + if (urlSearch) { this.searchText = urlSearch; } @@ -352,6 +365,7 @@ export default toNative(CrudTable); Promise } | undefined @@ -279,6 +330,101 @@ export default class ProjectStructuresTable extends Vue { :entity-props="{ structureId: selectedStructure?.id }" @close="closeModal" /> + + + + +
+

+ The structure must be published before it can contain data. Would you like to publish it? +

+
+ + +
+ + + + +
+
+
+ + + +
+
+

Are you sure you want to unpublish this structure?

+

+ All data saved under this structure will be permanently deleted. This action cannot be undone. +

+
+
+
+ + +
diff --git a/structures-frontend-next/src/components/StructuresList.vue b/structures-frontend-next/src/components/StructuresList.vue index 9bb1f0a93..31984af9e 100644 --- a/structures-frontend-next/src/components/StructuresList.vue +++ b/structures-frontend-next/src/components/StructuresList.vue @@ -3,6 +3,8 @@ import { Component, Vue, Prop, Ref, Watch } from "vue-facing-decorator"; import CrudTable from "@/components/CrudTable.vue"; import StructureDataViewModal from "@/components/modals/StructureDataViewModal.vue"; import StructureItemModal from "@/components/modals/StructureItemModal.vue"; +import Dialog from "primevue/dialog"; +import Button from "primevue/button"; import type { Identifiable, IterablePage, @@ -14,7 +16,7 @@ import type { CrudHeader } from "@/types/CrudHeader"; import DatetimeUtil from "@/util/DatetimeUtil"; @Component({ - components: { CrudTable, StructureDataViewModal, StructureItemModal }, + components: { CrudTable, StructureDataViewModal, StructureItemModal, Dialog, Button }, }) export default class StructuresList extends Vue { @Prop({ required: true }) applicationId!: string; @@ -37,6 +39,8 @@ export default class StructuresList extends Vue { showModal = false; showItemModal = false; + showPublishModal = false; + showUnpublishModal = false; selectedStructure: Structure | null = null; searchText = ""; isInitialized = false; @@ -139,9 +143,31 @@ export default class StructuresList extends Vue { this.selectedStructure = null; } + openPublishModal(item: Structure) { + this.selectedStructure = item; + this.showPublishModal = true; + } + + closePublishModal() { + this.showPublishModal = false; + this.selectedStructure = null; + } + + openUnpublishModal(item: Structure) { + this.selectedStructure = item; + this.showUnpublishModal = true; + } + + closeUnpublishModal() { + this.showUnpublishModal = false; + this.selectedStructure = null; + } + handleRowClick(item: Structure): void { if (item.published) { this.openModal(item); + } else { + this.openPublishModal(item); } } @@ -159,35 +185,54 @@ export default class StructuresList extends Vue { public async publish(item: any) { item["publishing"] = true; - if (confirm("Are you sure you want to Publish this Structure?")) { - let table: any = this.$refs?.crudTable; - try { - await this.dataSource1.publish(item.id); - table?.find(); - delete item["publishing"]; - } catch (error: any) { - delete item["publishing"]; - table?.displayAlert(error.message); - } + let table: any = this.$refs?.crudTable; + try { + await this.dataSource1.publish(item.id); + table?.find(); + delete item["publishing"]; + } catch (error: any) { + delete item["publishing"]; + table?.displayAlert(error.message); + } + } + + async publishFromModal() { + if (!this.selectedStructure) return; + + const item = this.selectedStructure as any; + item["publishing"] = true; + + try { + await this.dataSource1.publish(item.id); + this.closePublishModal(); + this.refreshTable(); + delete item["publishing"]; + } catch (error: any) { + delete item["publishing"]; + console.error('Error publishing structure:', error); + // You could add a toast notification here if needed } } public async unPublish(item: any) { + this.openUnpublishModal(item); + } + + async unpublishFromModal() { + if (!this.selectedStructure) return; + + const item = this.selectedStructure as any; item["publishing"] = true; - if ( - confirm( - "Are you sure you want to Remove Published Status for this Structure? \nAll data saved under this Structure will be permanently deleted, proceed with caution." - ) - ) { - let table: any = this.$refs?.crudTable; - try { - await this.dataSource1.unPublish(item.id); - table?.find(); - delete item["publishing"]; - } catch (error: any) { - delete item["publishing"]; - table?.displayAlert(error.message); - } + + try { + await this.dataSource1.unPublish(item.id); + this.closeUnpublishModal(); + this.refreshTable(); + delete item["publishing"]; + } catch (error: any) { + delete item["publishing"]; + console.error('Error unpublishing structure:', error); + // You could add a toast notification here if needed } } @@ -210,6 +255,10 @@ export default class StructuresList extends Vue { }, ]; } + + get isPublishing() { + return (this.selectedStructure as any)?.publishing || false; + } } @@ -282,5 +331,100 @@ export default class StructuresList extends Vue { :item="selectedStructure" @close="closeItemModal" /> + + + + +
+

+ The structure must be published before it can contain data. Would you like to publish it? +

+
+ + +
+ + + + +
+
+
+ + + +
+
+

Are you sure you want to unpublish this structure?

+

+ All data saved under this structure will be permanently deleted. This action cannot be undone. +

+
+
+
+ + +
\ No newline at end of file diff --git a/structures-frontend-next/src/components/modals/OpenAPIModal.vue b/structures-frontend-next/src/components/modals/OpenAPIModal.vue new file mode 100644 index 000000000..ae5376bdc --- /dev/null +++ b/structures-frontend-next/src/components/modals/OpenAPIModal.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/structures-frontend-next/src/pages/ApplicationDetails.vue b/structures-frontend-next/src/pages/ApplicationDetails.vue index 756686bf9..54e3c75ed 100644 --- a/structures-frontend-next/src/pages/ApplicationDetails.vue +++ b/structures-frontend-next/src/pages/ApplicationDetails.vue @@ -3,6 +3,7 @@ import { Component, Vue, Watch } from 'vue-facing-decorator' import ProjectList from '@/components/ProjectList.vue' import StructuresList from '@/components/StructuresList.vue' import GraphQLModal from '@/components/modals/GraphQLModal.vue' +import OpenAPIModal from '@/components/modals/OpenAPIModal.vue' import StructureItemModal from '@/components/modals/StructureItemModal.vue' import Tabs from 'primevue/tabs' import TabList from 'primevue/tablist' @@ -16,6 +17,7 @@ import { APPLICATION_STATE } from '@/states/IApplicationState' ProjectList, StructuresList, GraphQLModal, + OpenAPIModal, StructureItemModal, Tabs, TabList, @@ -27,6 +29,7 @@ import { APPLICATION_STATE } from '@/states/IApplicationState' export default class ApplicationDetails extends Vue { activeTab: string | number = 0 showGraphQLModal: boolean = false + showOpenAPIModal: boolean = false isInitialized: boolean = false get applicationId(): string { @@ -41,6 +44,10 @@ export default class ApplicationDetails extends Vue { return APPLICATION_STATE.structuresCount ?? 0 } + get currentApplication() { + return APPLICATION_STATE.currentApplication + } + get searchProduct(): string | undefined { return this.$route.query['search-project'] as string | undefined } @@ -92,6 +99,14 @@ export default class ApplicationDetails extends Vue { closeGraphQL(): void { this.showGraphQLModal = false } + + openOpenAPI(): void { + this.showOpenAPIModal = true + } + + closeOpenAPI(): void { + this.showOpenAPIModal = false + } } @@ -104,13 +119,18 @@ export default class ApplicationDetails extends Vue {
GraphQL
-
+
OpenAPI
@@ -143,6 +163,7 @@ export default class ApplicationDetails extends Vue { +
+ diff --git a/structures-frontend-next/src/pages/OpenAPIPlayground.vue b/structures-frontend-next/src/pages/OpenAPIPlayground.vue new file mode 100644 index 000000000..a4f36ecd7 --- /dev/null +++ b/structures-frontend-next/src/pages/OpenAPIPlayground.vue @@ -0,0 +1,35 @@ + + + diff --git a/structures-frontend-next/src/pages/login/Login.vue b/structures-frontend-next/src/pages/login/Login.vue index 2e58586cb..2a098be7c 100644 --- a/structures-frontend-next/src/pages/login/Login.vue +++ b/structures-frontend-next/src/pages/login/Login.vue @@ -1,6 +1,5 @@