Merge pull request #47564 from nextcloud/backport/47290/stable30

[stable30] feat(templates): add support for checkboxes in template filler
This commit is contained in:
Julius Härtl 2024-08-29 09:17:27 +02:00 committed by GitHub
commit 29a0e33b88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 257 additions and 39 deletions

View file

@ -9,11 +9,8 @@
<form>
<h3>{{ t('files', 'Fill template fields') }}</h3>
<!-- We will support more than just text fields in the future -->
<div v-for="field in fields" :key="field.index">
<TemplateTextField v-if="field.type == 'rich-text'"
:field="field"
@input="trackInput" />
<component :is="getFieldComponent(field.type)" :field="field" @input="trackInput" />
</div>
</form>
</div>
@ -29,11 +26,12 @@
</NcModal>
</template>
<script lang="ts">
<script>
import { defineComponent } from 'vue'
import { NcModal, NcButton, NcLoadingIcon } from '@nextcloud/vue'
import { translate as t } from '@nextcloud/l10n'
import TemplateTextField from './TemplateFiller/TemplateTextField.vue'
import TemplateRichTextField from './TemplateFiller/TemplateRichTextField.vue'
import TemplateCheckboxField from './TemplateFiller/TemplateCheckboxField.vue'
export default defineComponent({
name: 'TemplateFiller',
@ -42,7 +40,8 @@ export default defineComponent({
NcModal,
NcButton,
NcLoadingIcon,
TemplateTextField,
TemplateRichTextField,
TemplateCheckboxField,
},
props: {
@ -65,10 +64,21 @@ export default defineComponent({
methods: {
t,
trackInput([value, index]) {
this.localFields[index] = {
content: value,
trackInput({ index, property, value }) {
if (!this.localFields[index]) {
this.localFields[index] = {}
}
this.localFields[index][property] = value
},
getFieldComponent(fieldType) {
const fieldComponentType = fieldType.split('-')
.map((str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
.join('')
return `Template${fieldComponentType}Field`
},
async submit() {
this.loading = true

View file

@ -0,0 +1,68 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div class="template-field__checkbox">
<NcCheckboxRadioSwitch :id="fieldId"
:checked.sync="value"
type="switch"
@update:checked="input">
{{ fieldLabel }}
</NcCheckboxRadioSwitch>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
export default defineComponent({
name: 'TemplateCheckboxField',
components: {
NcCheckboxRadioSwitch,
},
props: {
field: {
type: Object,
default: () => {},
},
},
data() {
return {
value: this.field.checked ?? false,
}
},
computed: {
fieldLabel() {
const label = this.field.name ?? this.field.alias ?? 'Unknown field'
return label.charAt(0).toUpperCase() + label.slice(1)
},
fieldId() {
return 'checkbox-field' + this.field.index
},
},
methods: {
input() {
this.$emit('input', {
index: this.field.index,
property: 'checked',
value: this.value,
})
},
},
})
</script>
<style lang="scss" scoped>
.template-field__checkbox {
margin: 20px 0;
}
</style>

View file

@ -15,7 +15,7 @@
:label="fieldLabel"
:label-outside="true"
:placeholder="field.content"
@input="$emit('input', [value, field.index])" />
@input="input" />
</div>
</template>
@ -24,7 +24,7 @@ import { defineComponent } from 'vue'
import { NcTextField } from '@nextcloud/vue'
export default defineComponent({
name: 'TemplateTextField',
name: 'TemplateRichTextField',
components: {
NcTextField,
@ -53,6 +53,16 @@ export default defineComponent({
return 'text-field' + this.field.index
},
},
methods: {
input() {
this.$emit('input', {
index: this.field.index,
property: 'content',
value: this.value,
})
},
},
})
</script>

2
dist/1218-1218.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/1218-1218.js.map vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/1218-1218.js.map.license vendored Symbolic link
View file

@ -0,0 +1 @@
1218-1218.js.license

2
dist/7493-7493.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
7493-7493.js.license

4
dist/files-init.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -439,7 +439,10 @@ return array(
'OCP\\Files\\Storage\\IWriteStreamStorage' => $baseDir . '/lib/public/Files/Storage/IWriteStreamStorage.php',
'OCP\\Files\\Template\\BeforeGetTemplatesEvent' => $baseDir . '/lib/public/Files/Template/BeforeGetTemplatesEvent.php',
'OCP\\Files\\Template\\Field' => $baseDir . '/lib/public/Files/Template/Field.php',
'OCP\\Files\\Template\\FieldFactory' => $baseDir . '/lib/public/Files/Template/FieldFactory.php',
'OCP\\Files\\Template\\FieldType' => $baseDir . '/lib/public/Files/Template/FieldType.php',
'OCP\\Files\\Template\\Fields\\CheckBoxField' => $baseDir . '/lib/public/Files/Template/Fields/CheckBoxField.php',
'OCP\\Files\\Template\\Fields\\RichTextField' => $baseDir . '/lib/public/Files/Template/Fields/RichTextField.php',
'OCP\\Files\\Template\\FileCreatedFromTemplateEvent' => $baseDir . '/lib/public/Files/Template/FileCreatedFromTemplateEvent.php',
'OCP\\Files\\Template\\ICustomTemplateProvider' => $baseDir . '/lib/public/Files/Template/ICustomTemplateProvider.php',
'OCP\\Files\\Template\\ITemplateManager' => $baseDir . '/lib/public/Files/Template/ITemplateManager.php',

View file

@ -472,7 +472,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Files\\Storage\\IWriteStreamStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IWriteStreamStorage.php',
'OCP\\Files\\Template\\BeforeGetTemplatesEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Template/BeforeGetTemplatesEvent.php',
'OCP\\Files\\Template\\Field' => __DIR__ . '/../../..' . '/lib/public/Files/Template/Field.php',
'OCP\\Files\\Template\\FieldFactory' => __DIR__ . '/../../..' . '/lib/public/Files/Template/FieldFactory.php',
'OCP\\Files\\Template\\FieldType' => __DIR__ . '/../../..' . '/lib/public/Files/Template/FieldType.php',
'OCP\\Files\\Template\\Fields\\CheckBoxField' => __DIR__ . '/../../..' . '/lib/public/Files/Template/Fields/CheckBoxField.php',
'OCP\\Files\\Template\\Fields\\RichTextField' => __DIR__ . '/../../..' . '/lib/public/Files/Template/Fields/RichTextField.php',
'OCP\\Files\\Template\\FileCreatedFromTemplateEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Template/FileCreatedFromTemplateEvent.php',
'OCP\\Files\\Template\\ICustomTemplateProvider' => __DIR__ . '/../../..' . '/lib/public/Files/Template/ICustomTemplateProvider.php',
'OCP\\Files\\Template\\ITemplateManager' => __DIR__ . '/../../..' . '/lib/public/Files/Template/ITemplateManager.php',

View file

@ -12,37 +12,35 @@ namespace OCP\Files\Template;
/**
* @since 30.0.0
*/
class Field implements \JsonSerializable {
private string $index;
private string $content;
private FieldType $type;
private ?string $alias;
private ?int $id;
private ?string $tag;
abstract class Field implements \JsonSerializable {
public ?string $alias = null;
public ?string $tag = null;
public ?int $id = null;
/**
* @since 30.0.0
*/
public function __construct(string $index, string $content, FieldType $type, ?string $alias = null, ?int $id = null, ?string $tag = null) {
$this->index = $index;
$this->alias = $alias;
$this->type = $type;
$this->id = $id;
$this->tag = $tag;
$this->content = $content;
public function __construct(
private string $index,
private FieldType $type
) {
}
/**
* @since 30.0.0
*/
abstract public function setValue(mixed $value): void;
/**
* @since 30.0.0
*/
public function jsonSerialize(): array {
return [
"index" => $this->index,
"content" => $this->content,
"type" => $this->type->value,
"alias" => $this->alias,
"id" => $this->id,
"tag" => $this->tag,
'index' => $this->index,
'type' => $this->type->value,
'alias' => $this->alias,
'tag' => $this->tag,
'id' => $this->id,
];
}
}

View file

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\Files\Template;
use OCP\Files\Template\Fields\CheckBoxField;
use OCP\Files\Template\Fields\RichTextField;
/**
* @since 30.0.0
*/
class FieldFactory {
/**
* @since 30.0.0
*/
public static function createField(
string $index,
FieldType $type
): Field {
return match ($type) {
FieldType::RichText => new RichTextField($index, $type),
FieldType::CheckBox => new CheckBoxField($index, $type),
default => throw new InvalidFieldTypeException(),
};
}
}

View file

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\Files\Template\Fields;
use OCP\Files\Template\Field;
use OCP\Files\Template\FieldType;
/**
* @since 30.0.0
*/
class CheckBoxField extends Field {
private bool $checked = false;
/**
* @since 30.0.0
*/
public function __construct(string $index, FieldType $type) {
parent::__construct($index, $type);
}
/**
* @since 30.0.0
*/
public function setValue(mixed $value): void {
if (!is_bool($value)) {
throw new \Exception('Invalid value for checkbox field type');
}
$this->checked = $value;
}
/**
* @since 30.0.0
*/
public function jsonSerialize(): array {
$jsonProperties = parent::jsonSerialize();
return array_merge($jsonProperties, ['checked' => $this->checked]);
}
}

View file

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\Files\Template\Fields;
use OCP\Files\Template\Field;
use OCP\Files\Template\FieldType;
/**
* @since 30.0.0
*/
class RichTextField extends Field {
private string $content = '';
/**
* @since 30.0.0
*/
public function __construct(string $index, FieldType $type) {
parent::__construct($index, $type);
}
/**
* @since 30.0.0
*/
public function setValue(mixed $value): void {
if (!is_string($value)) {
throw new \Exception('Invalid value for rich-text field type');
}
$this->content = $value;
}
/**
* @since 30.0.0
*/
public function jsonSerialize(): array {
$jsonProperties = parent::jsonSerialize();
return array_merge($jsonProperties, ['content' => $this->content]);
}
}