Skip to content

Commit 652b3a0

Browse files
malbertsclaude
andcommitted
Add Boolean property type
Adds a `boolean` property type for true/false values, mirroring the recently-merged Select pattern. `BooleanValue` and the `ValueType::Boolean` deserialization path already existed in both PHP and TS; this PR adds the type wrapper, property definition, schema and subject UI, and registration. Schema JSON: `{ "type": "boolean" }`. No type-specific attributes; `default` may be `true`, `false`, or `null`. The construction-time check rejects non-boolean defaults, slightly stricter than siblings. `BooleanInput` always emits a `BooleanValue`, so a Boolean field is never "unset" once interacted with. The input renders as a single inline `label [switch]` row to match the `Require a value` row directly above it in the schema editor. Demo data: `Is public` on the Company schema (true on ACME Inc), plus three Boolean variants in the Everything showcase schema. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 674bf78 commit 652b3a0

20 files changed

Lines changed: 503 additions & 2 deletions

File tree

DemoData/Schema/Company.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
"World domination progress": {
4949
"type": "number",
5050
"default": 0
51+
},
52+
"Is public": {
53+
"type": "boolean"
5154
}
5255
}
5356
}

DemoData/Schema/Everything.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@
8181
],
8282
"multiple": true
8383
},
84+
"boolean/boolean": {
85+
"type": "boolean"
86+
},
87+
"boolean/boolean (default true)": {
88+
"type": "boolean",
89+
"default": true
90+
},
91+
"boolean/boolean (default false)": {
92+
"type": "boolean",
93+
"default": false
94+
},
8495
"relation/relation": {
8596
"type": "relation",
8697
"relation": "Has product",

DemoData/Subject/ACME_Inc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
"type": "number",
2424
"value": 42
2525
},
26+
"Is public": {
27+
"type": "boolean",
28+
"value": true
29+
},
2630
"Products": {
2731
"type": "relation",
2832
"value": [

docs/reference/schema-format.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,29 @@ Example:
199199
}
200200
```
201201

202+
### Boolean (`boolean`)
203+
204+
A true/false value, edited via a toggle switch and displayed as "Yes" or "No".
205+
206+
```json
207+
{
208+
"type": "boolean"
209+
}
210+
```
211+
212+
This type has no type-specific fields beyond the [common fields](#common-fields).
213+
The `default` may be `true`, `false`, or `null` (no default).
214+
215+
Example:
216+
217+
```json
218+
{
219+
"type": "boolean",
220+
"default": false,
221+
"description": "Whether the company is publicly traded"
222+
}
223+
```
224+
202225
## Reserved Property Types
203226

204227
The following types are defined in the JSON schema but not yet implemented:
@@ -211,7 +234,6 @@ The following types are defined in the JSON schema but not yet implemented:
211234
- `duration` - Time durations
212235
- `currency` - Monetary values
213236
- `progress` - Progress indicators
214-
- `checkbox` - Boolean checkbox
215237

216238
## REST API
217239

extension.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@
308308
"neowiki-property-type-select",
309309
"neowiki-property-type-datetime",
310310
"neowiki-property-type-date",
311+
"neowiki-property-type-boolean",
312+
"neowiki-boolean-true",
313+
"neowiki-boolean-false",
311314
"neowiki-infobox-type",
312315
"neowiki-infobox-edit-link",
313316
"neowiki-field-required",

i18n/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"neowiki-property-type-select": "Select",
2121
"neowiki-property-type-datetime": "Date & Time",
2222
"neowiki-property-type-date": "Date",
23+
"neowiki-property-type-boolean": "Boolean",
24+
"neowiki-boolean-true": "Yes",
25+
"neowiki-boolean-false": "No",
2326

2427
"neowiki-neojson-description": "Editing neo slot of \"$1\"",
2528

i18n/qqq.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@
144144
"neowiki-property-type-datetime": "Label for the date and time property type in the schema editor",
145145
"neowiki-field-invalid-date": "Validation error shown when the entered date value cannot be parsed. Date values must be strict ISO 8601 calendar dates in YYYY-MM-DD form with no time or timezone component (for example, '2025-06-15'). Values with a time part, partial values such as year-only, and calendar overflows such as '2025-02-30' are rejected, and min/max bounds are inclusive.",
146146
"neowiki-property-type-date": "Label for the date (without time) property type in the schema editor",
147+
"neowiki-property-type-boolean": "Label for the boolean (true/false) property type shown in the property type selector.",
148+
"neowiki-boolean-true": "Label shown in the value display for a boolean property whose value is true (e.g. in the infobox or schema-table 'Initial value' column).",
149+
"neowiki-boolean-false": "Label shown in the value display for a boolean property whose value is false (e.g. in the infobox or schema-table 'Initial value' column).",
147150
"neowiki-select-unknown-option": "Placeholder shown in a select-property display when a stored option ID cannot be resolved to a label (e.g. the option was removed from the Schema).",
148151

149152
"neowiki-managesubjects-tab": "Label for the Data tab that appears alongside the standard action tabs (View, Edit, History) on content pages, linking to the Subject management page.",

resources/ext.neowiki/src/Neo.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { RelationType } from '@/domain/propertyTypes/Relation';
55
import { UrlType } from '@/domain/propertyTypes/Url';
66
import { DateTimeType } from '@/domain/propertyTypes/DateTime';
77
import { DateType } from '@/domain/propertyTypes/Date';
8+
import { BooleanType } from '@/domain/propertyTypes/Boolean';
89
import { PropertyTypeRegistry } from '@/domain/PropertyType';
910
import { PropertyDefinitionDeserializer } from '@/domain/PropertyDefinition';
1011
import { ValueDeserializer } from '@/persistence/ValueDeserializer';
@@ -33,6 +34,7 @@ export class Neo {
3334
registry.registerType( new TextType() );
3435
registry.registerType( new NumberType() );
3536
registry.registerType( new SelectType() );
37+
registry.registerType( new BooleanType() );
3638
registry.registerType( new RelationType() );
3739
registry.registerType( new UrlType() );
3840
registry.registerType( new DateTimeType() );

resources/ext.neowiki/src/NeoWikiExtension.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import SelectDisplay from '@/components/Value/SelectDisplay.vue';
1212
import { RelationType } from '@/domain/propertyTypes/Relation.ts';
1313
import { DateTimeType } from '@/domain/propertyTypes/DateTime.ts';
1414
import { DateType } from '@/domain/propertyTypes/Date.ts';
15+
import { BooleanType } from '@/domain/propertyTypes/Boolean.ts';
16+
import BooleanDisplay from '@/components/Value/BooleanDisplay.vue';
1517
import { TypeSpecificComponentRegistry } from '@/TypeSpecificComponentRegistry.ts';
1618
import { ViewTypeRegistry } from '@/ViewTypeRegistry.ts';
1719
import Infobox from '@/components/Views/Infobox.vue';
@@ -20,6 +22,7 @@ import DateTimeDisplay from '@/components/Value/DateTimeDisplay.vue';
2022
import DateTimeInput from '@/components/Value/DateTimeInput.vue';
2123
import DateDisplay from '@/components/Value/DateDisplay.vue';
2224
import DateInput from '@/components/Value/DateInput.vue';
25+
import BooleanInput from '@/components/Value/BooleanInput.vue';
2326
import { HttpClient } from '@/infrastructure/HttpClient/HttpClient';
2427
import { ProductionHttpClient } from '@/infrastructure/HttpClient/ProductionHttpClient';
2528
import { RestSchemaRepository } from '@/persistence/RestSchemaRepository.ts';
@@ -48,14 +51,15 @@ import { MediaWikiPageSaver } from '@/persistence/MediaWikiPageSaver.ts';
4851
import { SubjectDeserializer } from '@/persistence/SubjectDeserializer.ts';
4952
import { Neo } from '@/Neo.ts';
5053
// import { cdxIconStringInteger } from '@/assets/CustomIcons.ts';
51-
import { cdxIconLink, cdxIconSearchCaseSensitive, cdxIconArticles, cdxIconListBullet, cdxIconMathematics, cdxIconClock, cdxIconCalendar } from '@wikimedia/codex-icons';
54+
import { cdxIconLink, cdxIconSearchCaseSensitive, cdxIconArticles, cdxIconListBullet, cdxIconMathematics, cdxIconClock, cdxIconCalendar, cdxIconCheck } from '@wikimedia/codex-icons';
5255
import TextAttributesEditor from '@/components/SchemaEditor/Property/TextAttributesEditor.vue';
5356
import NumberAttributesEditor from '@/components/SchemaEditor/Property/NumberAttributesEditor.vue';
5457
import SelectAttributesEditor from '@/components/SchemaEditor/Property/SelectAttributesEditor.vue';
5558
import UrlAttributesEditor from '@/components/SchemaEditor/Property/UrlAttributesEditor.vue';
5659
import RelationAttributesEditor from '@/components/SchemaEditor/Property/RelationAttributesEditor.vue';
5760
import DateTimeAttributesEditor from '@/components/SchemaEditor/Property/DateTimeAttributesEditor.vue';
5861
import DateAttributesEditor from '@/components/SchemaEditor/Property/DateAttributesEditor.vue';
62+
import BooleanAttributesEditor from '@/components/SchemaEditor/Property/BooleanAttributesEditor.vue';
5963
import { SubjectValidator } from '@/domain/SubjectValidator.ts';
6064
import { PropertyTypeRegistry } from '@/domain/PropertyType.ts';
6165
import { StoreStateLoader } from '@/persistence/StoreStateLoader.ts';
@@ -138,6 +142,14 @@ export class NeoWikiExtension {
138142
icon: cdxIconCalendar,
139143
} );
140144

145+
registry.registerType( BooleanType.typeName, {
146+
valueDisplayComponent: BooleanDisplay,
147+
valueEditor: BooleanInput,
148+
attributesEditor: BooleanAttributesEditor,
149+
label: 'neowiki-property-type-boolean',
150+
icon: cdxIconCheck,
151+
} );
152+
141153
return registry;
142154
}
143155

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<!-- cdx-field class is used for spacing -->
3+
<!-- Boolean properties have no type-specific attributes. -->
4+
<div class="boolean-attributes cdx-field" />
5+
</template>
6+
7+
<script setup lang="ts">
8+
import { BooleanProperty } from '@/domain/propertyTypes/Boolean.ts';
9+
import { AttributesEditorEmits, AttributesEditorProps } from '@/components/SchemaEditor/Property/AttributesEditorContract.ts';
10+
11+
defineProps<AttributesEditorProps<BooleanProperty>>();
12+
defineEmits<AttributesEditorEmits<BooleanProperty>>();
13+
</script>

0 commit comments

Comments
 (0)