Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions structures-frontend-next/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ declare module 'vue' {
Button: typeof import('primevue/button')['default']
Calendar: typeof import('primevue/calendar')['default']
Card: typeof import('primevue/card')['default']
CascadeSelect: typeof import('primevue/cascadeselect')['default']
Column: typeof import('primevue/column')['default']
Confirm: typeof import('./src/components/Confirm.vue')['default']
ConfirmDialog: typeof import('primevue/confirmdialog')['default']
Expand All @@ -24,6 +23,7 @@ declare module 'vue' {
DataTable: typeof import('primevue/datatable')['default']
Dialog: typeof import('primevue/dialog')['default']
EmptyState: typeof import('./src/components/EmptyState.vue')['default']
EntityListOld: typeof import('./src/components/EntityListOld.vue')['default']
EnumNode: typeof import('./src/components/nodes/EnumNode.vue')['default']
ERTable: typeof import('./src/components/modals/ERTable.vue')['default']
Glitch: typeof import('./src/components/Glitch.vue')['default']
Expand All @@ -38,11 +38,9 @@ declare module 'vue' {
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']
ProjectList: typeof import('./src/components/ProjectList.vue')['default']
ProjectStructuresTable: typeof import('./src/components/ProjectStructuresTable.vue')['default']
PropertyType: typeof import('./src/components/structures/flow-components/PropertyType.vue')['default']
RadioButton: typeof import('primevue/radiobutton')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SavedWidgetItem: typeof import('./src/components/SavedWidgetItem.vue')['default']
Expand Down
227 changes: 227 additions & 0 deletions structures-frontend-next/src/components/EntityListOld.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
<script lang="ts">
import { Component, Vue, Prop } from 'vue-facing-decorator'
import DataTable from 'primevue/datatable'
import Column from 'primevue/column'
import Toolbar from 'primevue/toolbar'
import Button from 'primevue/button'
import InputText from 'primevue/inputtext'

import { Pageable, type Page, Order, Direction, type Identifiable } from '@mindignited/continuum-client'
import { Structure, type IStructureService, Structures, type IEntitiesService } from '@mindignited/structures-api'

import DatetimeUtil from '@/util/DatetimeUtil'
import { StructureUtil } from '@/util/StructureUtil'

@Component({
components: {
DataTable,
Column,
Toolbar,
Button,
InputText
}
})
export default class EntityList extends Vue {
@Prop({ type: String }) structureId?: string

loading = false
finishedInitialLoad = false
items: Array<Identifiable<string>> = []
totalItems = 0
searchText: string | null = null

keys: string[] = []
headers: any[] = []
structureProperties: any = {}
structure!: Structure

entitiesService: IEntitiesService = Structures.getEntitiesService()
structureService: IStructureService = Structures.getStructureService()

options = {
rows: 10,
first: 0,
sortField: '',
sortOrder: 1
}

mounted() {
const paramId = this.$route.params.id
const id = this.structureId || (Array.isArray(paramId) ? paramId[0] : paramId)

if (!id) {
this.displayAlert("Missing structure ID.")
return
}

this.structureService.findById(id)
.then((structure) => {
this.structure = structure
this.structureProperties = structure.entityDefinition.properties
for (const property of this.structureProperties) {
if (property) {
const fieldName = property.name[0].toUpperCase() + property.name.slice(1)
let sortable = true
if (
['ref', 'array', 'object'].includes(property.type.type) ||
(property.type.type === 'string' && StructureUtil.hasDecorator('Text', property.decorators))
) {
sortable = false
}
const isComplex = ['ref', 'array', 'object'].includes(property.type.type)
const headerDef: any = {
header: fieldName,
field: property.name,
sortable: sortable,
width: property.name === 'id' ? 220 : (isComplex ? 240 : (sortable ? 120 : 160)),
isCollapsable: isComplex || property?.name === 'addresses' || property?.name === 'pet'
}
this.headers.push(headerDef)
this.keys.push(property.name)
}
}

this.find()
})
.catch((error) => {
console.error(`Error during structure retrieval: ${error.message}`)
this.displayAlert(error.message)
})
}

formatDate(date: string): string {
return DatetimeUtil.formatDate(date)
}

isDateField(field: string): boolean {
return StructureUtil.getPropertyDefinition(field, this.structureProperties)?.type?.type === 'date'
}

onPage(event: any) {
this.options.rows = event.rows
this.options.first = event.first
this.find()
}

onSort(event: any) {
this.options.sortField = event.sortField
this.options.sortOrder = event.sortOrder
this.find()
}

clearSearch() {
this.searchText = null
this.options.first = 0
this.find()
}

search() {
this.options.first = 0
this.find()
}

displayAlert(text: string) {
console.log(text)
// alert(text)
}

find() {
if (this.loading) return

this.loading = true

const page = this.options.first / this.options.rows
const orders: Order[] = []

if (this.options.sortField) {
orders.push(new Order(this.options.sortField, this.options.sortOrder === 1 ? Direction.ASC : Direction.DESC))
}

const pageable = Pageable.create(page, this.options.rows, { orders })
const paramId = this.$route.params.id
const id = this.structureId || (Array.isArray(paramId) ? paramId[0] : paramId)

const queryPromise = (this.searchText?.length)
? this.entitiesService.search(id, this.searchText, pageable)
: this.entitiesService.findAll(id, pageable)

queryPromise
.then((page: Page<any>) => {
this.items = page.content ?? []
this.totalItems = page.totalElements ?? 0
this.loading = false

if (!this.finishedInitialLoad) {
setTimeout(() => { this.finishedInitialLoad = true }, 500)
}
})
.catch((error: any) => {
this.displayAlert(error.message)
this.loading = false
if (!this.finishedInitialLoad) {
setTimeout(() => { this.finishedInitialLoad = true }, 500)
}
})
}
}
</script>

<template>
<div class="overflow-y-auto w-full">
<Toolbar class="!w-full">
<template #start>
<InputText
v-model="searchText"
placeholder="Search"
@keyup.enter="search"
@focus="($event.target as HTMLInputElement)?.select()"
class="w-1/2"
/>
<Button icon="pi pi-times" class="ml-2" v-if="searchText" @click="clearSearch" />
</template>
</Toolbar>

<DataTable :value="items" :loading="loading" :paginator="true" :rows="options.rows" :totalRecords="totalItems"
:first="options.first" :lazy="true" :sortField="options.sortField" :sortOrder="options.sortOrder" @page="onPage"
@sort="onSort" :scrollable="true" scrollHeight="flex" :resizableColumns="true" columnResizeMode="expand">
<template v-if="headers.length > 0">
<Column v-for="header in headers" :key="header.field" :field="header.field" :header="header.header"
:sortable="header.sortable" :style="{ width: header.width + 'px' }"
:class="[header.isCollapsable ? '!whitespace-normal' : '']">
<template #body="slotProps">
<div :class="[
header.isCollapsable
? 'whitespace-normal break-words w-[240px] max-w-[240px] text-sm'
: 'truncate'
]">
<span v-if="typeof slotProps.data[header.field] === 'object'">
{{ JSON.stringify(slotProps.data[header.field]) }}
</span>
<span v-else>
{{ isDateField(header.field)
? formatDate(slotProps.data[header.field])
: slotProps.data[header.field]
}}
</span>
</div>
</template>

</Column>
</template>

<template v-if="items.length === 0">
<div class="p-4 text-center">
<Button label="No Data - Push To Search Again" @click="find" v-if="!loading" />
</div>
</template>
</DataTable>
</div>
</template>
<style>
.p-datatable .p-button {
margin-top: 1rem;
}
.p-toolbar-start {
width: 100% !important;
}
</style>
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<script lang="ts">
import EntityList from "@/pages/EntityList.vue";
import EntityListOld from "@/components/EntityListOld.vue";
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";

@Component({
components: { EntityList }
components: { EntityList, EntityListOld }
})
export default class StructureDataViewModal extends Vue {
@Prop({ default: false }) readonly modelValue!: boolean;
@Prop({ default: "Data View" }) readonly title!: string;
@Prop({ default: () => ({}) }) readonly entityProps!: Record<string, unknown>;

showNewVersion = false;

get visible(): boolean {
return this.modelValue;
}
Expand Down Expand Up @@ -52,21 +55,34 @@ export default class StructureDataViewModal extends Vue {
this.visible = false;
this.emitClose();
}

toggleVersion() {
this.showNewVersion = !this.showNewVersion;
}
}
</script>
<template>
<div v-show="visible" class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div class="relative w-full h-screen bg-white shadow-lg overflow-hidden overflow-y-scroll">
<div class="flex items-center justify-between p-4 border-b border-gray-200">
<h3 class="text-xl font-semibold text-gray-900">{{ title }}</h3>
<button @click="onHide" class="text-gray-400 hover:text-gray-900 hover:bg-gray-200 rounded-lg text-sm w-8 h-8 flex items-center justify-center">
<svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
</button>
<div class="flex items-center gap-2">
<button
@click="toggleVersion"
class="px-3 py-1.5 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
>
{{ showNewVersion ? 'Old Version' : 'New Version' }}
</button>
<button @click="onHide" class="text-gray-400 hover:text-gray-900 hover:bg-gray-200 rounded-lg text-sm w-8 h-8 flex items-center justify-center">
<svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
</button>
</div>
</div>
<div class="h-full">
<EntityList v-bind="entityProps" />
<EntityListOld v-if="!showNewVersion" v-bind="entityProps" />
<EntityList v-else v-bind="entityProps" />
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion structures-frontend-next/src/pages/EntityList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,7 @@ export default EntityList
</div>
</div>
</template>
<style>
<style scoped>
.p-datatable .p-button {
margin-top: 1rem;
}
Expand Down
Loading