diff --git a/src/components/base/VPropertiesTable.vue b/src/components/base/VPropertiesTable.vue
index 5461baad..8e18fc93 100644
--- a/src/components/base/VPropertiesTable.vue
+++ b/src/components/base/VPropertiesTable.vue
@@ -1,8 +1,10 @@
@@ -10,43 +12,13 @@ const props = defineProps<{
- {{ property[0] }} |
+ {{ property.name }} |
-
- <empty>
-
-
-
-
- {{ item }}
-
-
-
-
-
+
|
-
diff --git a/src/components/base/VPropertyTableValue.vue b/src/components/base/VPropertyTableValue.vue
new file mode 100644
index 00000000..d376408b
--- /dev/null
+++ b/src/components/base/VPropertyTableValue.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+ <empty>
+
+
+
+
+
+
+
+ <empty>
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ propertyValue.value.value }}
+
+
+
+
+ {{ propertyValue.value.value }}
+
+
+ {{ propertyValue.value.description }}
+
+
+
+
+
+ {{ propertyValue.value.toString() }}
+
+
+
+
+
+
+ {{ propertyValue.note }}
+
+
+
+
+
+
+
+
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAssociatedDatum.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAssociatedDatum.vue
index 70e22b9f..e463a5af 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAssociatedDatum.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAssociatedDatum.vue
@@ -3,18 +3,20 @@ import LabEditorViewerNameVariants from './LabEditorSchemaViewerNameVariants.vue
import LabEditorViewerContainer from './LabEditorSchemaViewerContainer.vue'
import { SchemaViewerDataPointer } from '@/model/editor/schema-viewer'
import { AssociatedDataSchema } from '@/model/evitadb'
+import { KeywordValue, Property, PropertyValue } from '@/model/properties-table'
const props = defineProps<{
dataPointer: SchemaViewerDataPointer,
schema: AssociatedDataSchema
}>()
-const properties: [string, any, ((item?: string) => void)?][] = []
-properties.push(['Type', props.schema.type.replace('ComplexDataObject', 'Object')])
-properties.push(['Description', props.schema.description])
-properties.push(['Deprecation notice', props.schema.deprecationNotice])
-properties.push(['Localized', props.schema.localized as boolean])
-properties.push(['Nullable', props.schema.nullable as boolean])
+const properties: Property[] = [
+ { name: 'Type', value: new PropertyValue(new KeywordValue(props.schema.type.replace('ComplexDataObject', 'Object'))) },
+ { name: 'Description', value: new PropertyValue(props.schema.description) },
+ { name: 'Deprecation notice', value: new PropertyValue(props.schema.deprecationNotice) },
+ { name: 'Localized', value: new PropertyValue(props.schema.localized as boolean) },
+ { name: 'Nullable', value: new PropertyValue(props.schema.nullable as boolean) }
+]
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAttribute.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAttribute.vue
index 509abba9..dc815a57 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAttribute.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerAttribute.vue
@@ -1,30 +1,83 @@
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerCatalog.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerCatalog.vue
index 19f8097b..fd388b81 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerCatalog.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerCatalog.vue
@@ -6,16 +6,17 @@ import LabEditorViewerAttributes from './LabEditorSchemaViewerAttributes.vue'
import LabEditorViewerContainer from './LabEditorSchemaViewerContainer.vue'
import LabEditorSchemaViewerEntities from './LabEditorSchemaViewerEntities.vue'
import { CatalogSchema } from '@/model/evitadb'
+import { Property, PropertyValue } from '@/model/properties-table'
const props = defineProps<{
dataPointer: SchemaViewerDataPointer,
schema: CatalogSchema
}>()
-const baseProperties = ref<[string, any, ((item?: string) => void)?][]>([
+const baseProperties = ref([
// todo lho i18n
- ['Version', props.schema.version],
- ['Description', props.schema.description]
+ { name: 'Version', value: new PropertyValue(props.schema.version) },
+ { name: 'Description', value: new PropertyValue(props.schema.description) }
])
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerContainer.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerContainer.vue
index 359dd541..1bf7e24e 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerContainer.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerContainer.vue
@@ -1,8 +1,9 @@
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerEntity.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerEntity.vue
index 17143c9a..97733561 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerEntity.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerEntity.vue
@@ -7,24 +7,25 @@ import LabEditorViewerContainer from './LabEditorSchemaViewerContainer.vue'
import LabEditorSchemaViewerAssociatedData from './LabEditorSchemaViewerAssociatedData.vue'
import LabEditorSchemaViewerReferences from './LabEditorSchemaViewerReferences.vue'
import { EntitySchema } from '@/model/evitadb'
+import { KeywordValue, Property, PropertyValue } from '@/model/properties-table'
const props = defineProps<{
dataPointer: SchemaViewerDataPointer,
schema: EntitySchema
}>()
-const baseProperties = ref<[string, any, ((item?: string) => void)?][]>([
+const baseProperties = ref([
// todo lho i18n
- ['Version', props.schema.version],
- ['Description', props.schema.description],
- ['Deprecation notice', props.schema.deprecationNotice],
- ['Locales', props.schema.locales],
- ['Currencies', props.schema.currencies],
- ['Generated primary key', props.schema.withGeneratedPrimaryKey],
- ['Hierarchical', props.schema.withHierarchy],
- ['Prices', props.schema.withPrice],
- ['Indexed decimal places', props.schema.indexedPricePlaces],
- ['Evolution modes', props.schema.evolutionMode]
+ { name: 'Version', value: new PropertyValue(props.schema.version) },
+ { name: 'Description', value: new PropertyValue(props.schema.description) },
+ { name: 'Deprecation notice', value: new PropertyValue(props.schema.deprecationNotice) },
+ { name: 'Locales', value: props.schema.locales.map(locale => new PropertyValue(new KeywordValue(locale))) },
+ { name: 'Currencies', value: props.schema.currencies.map(currency => new PropertyValue(new KeywordValue(currency))) },
+ { name: 'Generated primary key', value: new PropertyValue(props.schema.withGeneratedPrimaryKey) },
+ { name: 'Hierarchical', value: new PropertyValue(props.schema.withHierarchy) },
+ { name: 'Prices', value: new PropertyValue(props.schema.withPrice) },
+ { name: 'Indexed decimal places', value: new PropertyValue(props.schema.indexedPricePlaces) },
+ { name: 'Evolution modes', value: props.schema.evolutionMode.map(mode => new PropertyValue(new KeywordValue(mode))) }
])
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerNameVariants.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerNameVariants.vue
index 45391f82..a76a45db 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerNameVariants.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerNameVariants.vue
@@ -2,6 +2,7 @@
import LabEditorSchemaViewerContainerSection from './LabEditorSchemaViewerContainerSection.vue'
import { NameVariants } from '@/model/evitadb'
import VPropertiesTable from '@/components/base/VPropertiesTable.vue'
+import { Property, PropertyValue } from '@/model/properties-table'
const props = withDefaults(defineProps<{
prefix?: string,
@@ -12,12 +13,12 @@ const props = withDefaults(defineProps<{
const name = props.prefix ? `${props.prefix} name variants` : 'Name variants'
-const properties: [string, any, ((item?: string) => void)?][] = [
- ['camelCase', props.nameVariants.camelCase as String],
- ['kebab-case', props.nameVariants.kebabCase as String],
- ['PascalCase', props.nameVariants.pascalCase as String],
- ['snake_case', props.nameVariants.snakeCase as String],
- ['UPPER_CASE', props.nameVariants.upperSnakeCase as String]
+const properties: Property[] = [
+ { name: 'camelCase', value: new PropertyValue(props.nameVariants.camelCase as String) },
+ { name: 'kebab-case', value: new PropertyValue(props.nameVariants.kebabCase as String) },
+ { name: 'PascalCase', value: new PropertyValue(props.nameVariants.pascalCase as String) },
+ { name: 'snake_case', value: new PropertyValue(props.nameVariants.snakeCase as String) },
+ { name: 'UPPER_CASE', value: new PropertyValue(props.nameVariants.upperSnakeCase as String) }
]
diff --git a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerReference.vue b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerReference.vue
index 736d7422..dfc2c30a 100644
--- a/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerReference.vue
+++ b/src/components/lab/editor/schema-viewer/LabEditorSchemaViewerReference.vue
@@ -6,6 +6,7 @@ import LabEditorSchemaViewerAttributes from './LabEditorSchemaViewerAttributes.v
import { EditorService, useEditorService } from '@/services/editor/editor.service'
import { SchemaViewerRequest } from '@/model/editor/schema-viewer-request'
import { ReferenceSchema } from '@/model/evitadb'
+import { KeywordValue, Property, PropertyValue } from '@/model/properties-table'
const editorService: EditorService = useEditorService()
@@ -14,54 +15,62 @@ const props = defineProps<{
schema: ReferenceSchema
}>()
-const properties: [string, any, ((item?: string) => void)?][] = []
-properties.push(['Description', props.schema.description])
-properties.push(['Deprecation notice', props.schema.deprecationNotice])
-properties.push(['Cardinality', [props.schema.cardinality]])
+const properties: Property[] = []
+properties.push({ name: 'Description', value: new PropertyValue(props.schema.description) })
+properties.push({ name: 'Deprecation notice', value: new PropertyValue(props.schema.deprecationNotice) })
+properties.push({ name: 'Cardinality', value: new PropertyValue(new KeywordValue(props.schema.cardinality)) })
if (props.schema.referencedEntityTypeManaged) {
- properties.push([
- 'Referenced entity',
- [props.schema.referencedEntityType],
- item => {
- editorService.createTabRequest(new SchemaViewerRequest(
- props.dataPointer.connection,
- new EntitySchemaPointer(
- props.dataPointer.schemaPointer.catalogName,
- props.schema.referencedEntityType
- )
- ))
- }
- ])
+ properties.push({
+ name: 'Referenced entity',
+ value: new PropertyValue(
+ new KeywordValue(props.schema.referencedEntityType),
+ undefined,
+ item => {
+ editorService.createTabRequest(new SchemaViewerRequest(
+ props.dataPointer.connection,
+ new EntitySchemaPointer(
+ props.dataPointer.schemaPointer.catalogName,
+ props.schema.referencedEntityType
+ )
+ ))
+ }
+ ),
+ })
} else {
- properties.push([
- 'Referenced entity',
- [props.schema.referencedEntityType]
- ])
+ properties.push({
+ name: 'Referenced entity',
+ value: new PropertyValue(new KeywordValue(props.schema.referencedEntityType))
+ })
}
-properties.push(['Referenced entity managed', props.schema.referencedEntityTypeManaged])
-if (props.schema.referencedGroupTypeManaged) {
- properties.push([
- 'Referenced group',
- props.schema.referencedGroupType ? [props.schema.referencedGroupType] : undefined,
- item => {
- editorService.createTabRequest(new SchemaViewerRequest(
- props.dataPointer.connection,
- new EntitySchemaPointer(
- props.dataPointer.schemaPointer.catalogName,
- props.schema.referencedEntityType
- )
- ))
- }
- ])
+properties.push({ name: 'Referenced entity managed', value: new PropertyValue(props.schema.referencedEntityTypeManaged) })
+if (props.schema.referencedGroupType == undefined) {
+ properties.push({ name: 'Referenced group', value: new PropertyValue(undefined) })
+} else if (props.schema.referencedGroupTypeManaged) {
+ properties.push({
+ name: 'Referenced group',
+ value: new PropertyValue(
+ props.schema.referencedGroupType ? new KeywordValue(props.schema.referencedGroupType) : undefined,
+ undefined,
+ item => {
+ editorService.createTabRequest(new SchemaViewerRequest(
+ props.dataPointer.connection,
+ new EntitySchemaPointer(
+ props.dataPointer.schemaPointer.catalogName,
+ props.schema.referencedGroupType as string
+ )
+ ))
+ }
+ )
+ })
} else {
- properties.push([
- 'Referenced group',
- props.schema.referencedGroupType ? [props.schema.referencedGroupType] : undefined
- ])
+ properties.push({
+ name: 'Referenced group',
+ value: new PropertyValue(props.schema.referencedGroupType ? new KeywordValue(props.schema.referencedGroupType) : undefined)
+ })
}
-properties.push(['Referenced group managed', props.schema.referencedGroupTypeManaged])
-properties.push(['Indexed', props.schema.indexed])
-properties.push(['Faceted', props.schema.faceted])
+properties.push({ name: 'Referenced group managed', value: new PropertyValue(props.schema.referencedGroupTypeManaged) })
+properties.push({ name: 'Indexed', value: new PropertyValue(props.schema.indexed) })
+properties.push({ name: 'Faceted', value: new PropertyValue(props.schema.faceted) })
diff --git a/src/model/evitadb.ts b/src/model/evitadb.ts
index d5d62aa9..9df087ec 100644
--- a/src/model/evitadb.ts
+++ b/src/model/evitadb.ts
@@ -161,7 +161,7 @@ export interface AttributeSchema {
/**
* When attribute is unique it is automatically filterable, and it is ensured there is exactly one single entity having certain value of this attribute among other entities in the same collection. As an example of unique attribute can be EAN - there is no sense in having two entities with same EAN, and it's better to have this ensured by the database engine.
*/
- unique: boolean;
+ uniquenessType: AttributeUniquenessType;
/**
* Contains unique name of the model. Case-sensitive. Distinguishes one model item from another within single entity instance.
*/
@@ -176,6 +176,42 @@ export interface AttributeSchema {
*/
export type AttributeSchemaUnion = AttributeSchema | EntityAttributeSchema | GlobalAttributeSchema;
+export enum AttributeUniquenessType {
+
+ /**
+ * The attribute is not unique (default).
+ */
+ NotUnique = 'NOT_UNIQUE',
+ /**
+ * The attribute value must be unique among all the entities of the same collection.
+ */
+ UniqueWithinCollection = 'UNIQUE_WITHIN_COLLECTION',
+ /**
+ * The localized attribute value must be unique among all values of the same locale among all the entities
+ * using of the same collection.
+ */
+ UniqueWithinCollectionLocale = 'UNIQUE_WITHIN_COLLECTION_LOCALE'
+}
+
+export enum GlobalAttributeUniquenessType {
+
+ /**
+ * The attribute is not unique (default).
+ */
+ NotUnique = 'NOT_UNIQUE',
+ /**
+ * The attribute value (either localized or non-localized) must be unique among all values among all the entities
+ * using this {@link GlobalAttributeSchema} in the entire catalog.
+ */
+ UniqueWithinCatalog = 'UNIQUE_WITHIN_CATALOG',
+ /**
+ * The localized attribute value must be unique among all values of the same locale among all the entities
+ * using this {@link GlobalAttributeSchema} in the entire catalog.
+ */
+ UniqueWithinCatalogLocale = 'UNIQUE_WITHIN_CATALOG_LOCALE'
+
+}
+
export enum Cardinality {
ZeroOrOne = 'ZERO_OR_ONE',
ExactlyOne = 'EXACTLY_ONE',
@@ -577,7 +613,7 @@ export interface EntityAttributeSchema {
/**
* When attribute is unique it is automatically filterable, and it is ensured there is exactly one single entity having certain value of this attribute among other entities in the same collection. As an example of unique attribute can be EAN - there is no sense in having two entities with same EAN, and it's better to have this ensured by the database engine.
*/
- unique: boolean;
+ uniquenessType: AttributeUniquenessType;
/**
* Contains unique name of the model. Case-sensitive. Distinguishes one model item from another within single entity instance.
*/
@@ -634,7 +670,7 @@ export interface GlobalAttributeSchema {
/**
* When attribute is unique it is automatically filterable, and it is ensured there is exactly one single entity having certain value of this attribute among other entities in the same collection. As an example of unique attribute can be EAN - there is no sense in having two entities with same EAN, and it's better to have this ensured by the database engine.
*/
- unique: boolean;
+ uniquenessType: AttributeUniquenessType;
/**
* Contains unique name of the model. Case-sensitive. Distinguishes one model item from another within single entity instance.
*/
@@ -646,7 +682,7 @@ export interface GlobalAttributeSchema {
/**
* When attribute is unique globally it is automatically filterable, and it is ensured there is exactly one single entity having certain value of this attribute in entire catalog. As an example of unique attribute can be URL - there is no sense in having two entities with same URL, and it's better to have this ensured by the database engine.
*/
- uniqueGlobally: boolean;
+ globalUniquenessType: GlobalAttributeUniquenessType;
}
/**
* Contains all global attributes schemas relevant for parent schema.
diff --git a/src/model/properties-table.ts b/src/model/properties-table.ts
new file mode 100644
index 00000000..eb410280
--- /dev/null
+++ b/src/model/properties-table.ts
@@ -0,0 +1,78 @@
+/**
+ * Single property of a table (row)
+ */
+export type Property = {
+ /**
+ * Name of the property
+ */
+ name: string
+ /**
+ * Value of the property
+ */
+ value: PropertyValue | PropertyValue[]
+}
+
+/**
+ * Holder of a single value of a property
+ */
+export class PropertyValue {
+ /**
+ * Actual value of the property
+ */
+ readonly value: undefined | boolean | string | number | KeywordValue | ComplexFlagValue
+ /**
+ * Side note of this value
+ */
+ readonly note?: string
+ /**
+ * Action to be performed when this value is clicked
+ */
+ readonly action?: ((item?: string) => void)
+
+ constructor(value: undefined | boolean | string | number | KeywordValue | ComplexFlagValue, note?: string, action?: ((item?: string) => void)) {
+ this.value = value
+ this.note = note
+ this.action = action
+ }
+}
+
+/**
+ * Actual specific value of a property representing a keyword (e.g., data type, enum item,...)
+ */
+export class KeywordValue {
+ /**
+ * String representation of the value
+ */
+ readonly value: string
+
+ constructor(value: string) {
+ this.value = value
+ }
+
+ toString() {
+ return this.value
+ }
+}
+
+/**
+ * Actual specific value of a property representing a multiple-state flag (not just yes/no).
+ */
+export class ComplexFlagValue {
+ /**
+ * String representation of the current state
+ */
+ readonly value: string
+ /**
+ * Description of the current state
+ */
+ readonly description?: string
+
+ constructor(value: string, description?: string) {
+ this.value = value
+ this.description = description
+ }
+
+ toString() {
+ return this.value
+ }
+}
diff --git a/src/services/lab.service.ts b/src/services/lab.service.ts
index 82c57251..2a05ffda 100644
--- a/src/services/lab.service.ts
+++ b/src/services/lab.service.ts
@@ -6,10 +6,13 @@ import { EvitaDBClient } from '@/services/evitadb-client'
import {
AssociatedDataSchema,
AttributeSchemaUnion,
+ AttributeUniquenessType,
Catalog,
- CatalogSchema, EntityAttributeSchema,
+ CatalogSchema,
+ EntityAttributeSchema,
EntitySchema,
GlobalAttributeSchema,
+ GlobalAttributeUniquenessType,
ReferenceSchema
} from '@/model/evitadb'
import { EvitaDBDocsClient } from '@/services/evitadb-docs-client'
@@ -140,17 +143,20 @@ export class LabService {
getAttributeSchemaFlags = (schema: AttributeSchemaUnion): string[] => {
const flags: string[] = []
flags.push(this.formatDataTypeForFlag(schema.type))
- const globalAttribute = 'uniqueGlobally' in schema
+ const globalAttribute = 'globalUniquenessType' in schema
const entityAttribute = 'representative' in schema
if (entityAttribute && (schema as EntityAttributeSchema).representative) {
flags.push('representative')
}
- if (globalAttribute && (schema as GlobalAttributeSchema).uniqueGlobally) {
- flags.push('unique globally')
- } else if (schema.unique) {
+ if (globalAttribute && (schema as GlobalAttributeSchema).globalUniquenessType != GlobalAttributeUniquenessType.NotUnique) {
+ flags.push('globally unique')
+ } else if (schema.uniquenessType != AttributeUniquenessType.NotUnique) {
flags.push('unique')
}
- if (schema.unique || schema.filterable) flags.push('filterable')
+ if ((globalAttribute && (schema as GlobalAttributeSchema).globalUniquenessType != GlobalAttributeUniquenessType.NotUnique) ||
+ schema.uniquenessType != AttributeUniquenessType.NotUnique ||
+ schema.filterable)
+ flags.push('filterable')
if (schema.sortable) flags.push('sortable')
if (schema.localized) flags.push('localized')
if (schema.nullable) flags.push('nullable')