chg: [metaTemplate] Started refactoring the whole feature
Objective of the refactoring is to: Simplified metafields searches and started to add support of multi-field and editionpull/93/head
parent
51d93d40af
commit
9373c35bc6
|
@ -121,12 +121,20 @@ class CRUDComponent extends Component
|
|||
->where([
|
||||
'scope' => $this->Table->metaFields,
|
||||
'enabled' => 1
|
||||
]);
|
||||
$metaQuery->contain(['MetaTemplateFields']);
|
||||
])
|
||||
->contain('MetaTemplateFields')
|
||||
->formatResults(function (\Cake\Collection\CollectionInterface $metaTemplates) { // Set meta-template && meta-template-fields indexed by their ID
|
||||
return $metaTemplates
|
||||
->map(function($metaTemplate) {
|
||||
$metaTemplate->meta_template_fields = Hash::combine($metaTemplate->meta_template_fields, '{n}.id', '{n}');
|
||||
return $metaTemplate;
|
||||
})
|
||||
->indexBy('id');
|
||||
});
|
||||
$metaTemplates = $metaQuery->all();
|
||||
}
|
||||
$this->Controller->set('metaTemplates', $metaTemplates);
|
||||
return true;
|
||||
return $metaTemplates;
|
||||
}
|
||||
|
||||
public function add(array $params = []): void
|
||||
|
@ -258,13 +266,14 @@ class CRUDComponent extends Component
|
|||
if (empty($id)) {
|
||||
throw new NotFoundException(__('Invalid {0}.', $this->ObjectAlias));
|
||||
}
|
||||
$this->getMetaTemplates();
|
||||
$metaTemplates = $this->getMetaTemplates();
|
||||
if ($this->taggingSupported()) {
|
||||
$params['contain'][] = 'Tags';
|
||||
$this->setAllTags();
|
||||
}
|
||||
$data = $this->Table->get($id, isset($params['get']) ? $params['get'] : $params);
|
||||
$data = $this->getMetaFields($id, $data);
|
||||
$data = $this->attachMetaTemplates($data, $metaTemplates->toArray());
|
||||
// $data = $this->getMetaFields($id, $data);
|
||||
if (!empty($params['fields'])) {
|
||||
$this->Controller->set('fields', $params['fields']);
|
||||
}
|
||||
|
@ -273,6 +282,7 @@ class CRUDComponent extends Component
|
|||
'associated' => []
|
||||
];
|
||||
$input = $this->__massageInput($params);
|
||||
dd($input);
|
||||
if (!empty($params['fields'])) {
|
||||
$patchEntityParams['fields'] = $params['fields'];
|
||||
}
|
||||
|
@ -356,7 +366,22 @@ class CRUDComponent extends Component
|
|||
return $metaTemplates;
|
||||
}
|
||||
|
||||
public function getMetaFields($id, $data)
|
||||
// public function getMetaFields($id, $data)
|
||||
// {
|
||||
// if (empty($this->Table->metaFields)) {
|
||||
// return $data;
|
||||
// }
|
||||
// $query = $this->MetaFields->find();
|
||||
// $query->where(['MetaFields.scope' => $this->Table->metaFields, 'MetaFields.parent_id' => $id]);
|
||||
// $metaFields = $query->all();
|
||||
// $data['metaFields'] = [];
|
||||
// foreach($metaFields as $metaField) {
|
||||
// // $data['metaFields'][$metaField->meta_template_id][$metaField->field] = $metaField->value;
|
||||
// $data['metaFields'][$metaField->meta_template_id][$metaField->meta_template_field_id] = $metaField->value;
|
||||
// }
|
||||
// return $data;
|
||||
// }
|
||||
public function getMetaFields($id)
|
||||
{
|
||||
if (empty($this->Table->metaFields)) {
|
||||
return $data;
|
||||
|
@ -364,13 +389,34 @@ class CRUDComponent extends Component
|
|||
$query = $this->MetaFields->find();
|
||||
$query->where(['MetaFields.scope' => $this->Table->metaFields, 'MetaFields.parent_id' => $id]);
|
||||
$metaFields = $query->all();
|
||||
$data['metaFields'] = [];
|
||||
$data = [];
|
||||
foreach($metaFields as $metaField) {
|
||||
$data['metaFields'][$metaField->meta_template_id][$metaField->field] = $metaField->value;
|
||||
if (empty($data[$metaField->meta_template_id][$metaField->meta_template_field_id])) {
|
||||
$data[$metaField->meta_template_id][$metaField->meta_template_field_id] = [];
|
||||
}
|
||||
$data[$metaField->meta_template_id][$metaField->meta_template_field_id][$metaField->id] = $metaField;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function attachMetaTemplates($data, $metaTemplates)
|
||||
{
|
||||
$metaFields = $this->getMetaFields($data->id, $data);
|
||||
foreach ($metaTemplates as $i => $metaTemplate) {
|
||||
if (isset($metaFields[$metaTemplate->id])) {
|
||||
foreach ($metaTemplate->meta_template_fields as $j => $meta_template_field) {
|
||||
if (isset($metaFields[$metaTemplate->id][$meta_template_field->id])) {
|
||||
$metaTemplates[$metaTemplate->id]->meta_template_fields[$j]['metaFields'] = $metaFields[$metaTemplate->id][$meta_template_field->id];
|
||||
} else {
|
||||
$metaTemplates[$metaTemplate->id]->meta_template_fields[$j]['metaFields'] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['MetaTemplates'] = $metaTemplates;
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function view(int $id, array $params = []): void
|
||||
{
|
||||
if (empty($id)) {
|
||||
|
@ -767,7 +813,7 @@ class CRUDComponent extends Component
|
|||
$modelAlias = $this->Table->getAlias();
|
||||
$subQuery = $this->Table->find('tagged', [
|
||||
'name' => $tags,
|
||||
'forceAnd' => true
|
||||
'OperatorAND' => true
|
||||
])->select($modelAlias . '.id');
|
||||
return $query->where([$modelAlias . '.id IN' => $subQuery]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
<?php
|
||||
|
||||
namespace App\Model\Behavior;
|
||||
|
||||
use Cake\ORM\Behavior;
|
||||
use Cake\ORM\Entity;
|
||||
use Cake\ORM\Query;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\Utility\Inflector;
|
||||
use Cake\Database\Expression\QueryExpression;
|
||||
|
||||
use function PHPSTORM_META\type;
|
||||
|
||||
class MetaFieldsBehavior extends Behavior
|
||||
{
|
||||
protected $_defaultConfig = [
|
||||
'metaFieldsAssoc' => [
|
||||
'className' => 'MetaFields',
|
||||
'foreignKey' => 'parent_id',
|
||||
'bindingKey' => 'id',
|
||||
'dependent' => true,
|
||||
'cascadeCallbacks' => true,
|
||||
'saveStrategy' => 'append',
|
||||
'propertyName' => 'meta_fields',
|
||||
],
|
||||
'modelAssoc' => [
|
||||
'foreignKey' => 'parent_id',
|
||||
'bindingKey' => 'id',
|
||||
],
|
||||
'metaTemplateFieldCounter' => ['counter'],
|
||||
|
||||
'implementedEvents' => [
|
||||
'Model.beforeMarshal' => 'beforeMarshal',
|
||||
'Model.beforeFind' => 'beforeFind',
|
||||
'Model.beforeSave' => 'beforeSave',
|
||||
],
|
||||
'implementedMethods' => [
|
||||
'normalizeMetafields' => 'normalizeMetafields',
|
||||
],
|
||||
'implementedFinders' => [
|
||||
'metafieldValue' => 'findMetafieldValue',
|
||||
],
|
||||
];
|
||||
|
||||
public function initialize(array $config): void
|
||||
{
|
||||
$this->bindAssociations();
|
||||
$this->attachCounters();
|
||||
$this->_metaTemplateFieldTable = $this->_table;
|
||||
$this->_metaTemplateTable = $this->_table;
|
||||
}
|
||||
|
||||
public function bindAssociations()
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
$metaFieldsAssoc = $config['metaFieldsAssoc'];
|
||||
$modelAssoc = $config['modelAssoc'];
|
||||
|
||||
$table = $this->_table;
|
||||
$tableAlias = $this->_table->getAlias();
|
||||
|
||||
$assocConditions = [
|
||||
'MetaFields.scope' => Inflector::underscore(Inflector::singularize($tableAlias))
|
||||
];
|
||||
if (!$table->hasAssociation('MetaFields')) {
|
||||
$table->hasMany('MetaFields', array_merge(
|
||||
$metaFieldsAssoc,
|
||||
[
|
||||
'conditions' => $assocConditions
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
if (!$table->MetaFields->hasAssociation($tableAlias)) {
|
||||
$table->MetaFields->belongsTo($tableAlias, array_merge(
|
||||
$modelAssoc,
|
||||
[
|
||||
'className' => get_class($table),
|
||||
]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function attachCounters()
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
$metaFieldsTable = $this->_table->MetaFields;
|
||||
$tableAlias = $this->_table->getAlias();
|
||||
|
||||
if (!$metaFieldsTable->hasBehavior('CounterCache')) {
|
||||
$metaFieldsTable->addBehavior('CounterCache', [
|
||||
$tableAlias => $config['metaTemplateFieldCounter']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function beforeMarshal($event, $data, $options)
|
||||
{
|
||||
$property = $this->getConfig('metaFieldsAssoc.propertyName');
|
||||
$options['accessibleFields'][$property] = true;
|
||||
$options['associated']['MetaFields']['accessibleFields']['id'] = true;
|
||||
|
||||
if (isset($data[$property])) {
|
||||
if (!empty($data[$property])) {
|
||||
$data[$property] = $this->normalizeMetafields($data[$property]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function beforeSave($event, $entity, $options)
|
||||
{
|
||||
if (empty($entity->metaFields)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public function normalizeMetafields($metaFields)
|
||||
{
|
||||
return $metaFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* $this->{$model}->find('metaFieldValue', [
|
||||
* ['meta_template_id' => 1, 'field' => 'email', 'value' => '%@domain.test'],
|
||||
* ['meta_template_id' => 1, 'field' => 'country_code', 'value' => '!LU'],
|
||||
* ['meta_template_id' => 1, 'field' => 'time_zone', 'value' => 'UTC+2'],
|
||||
* ])
|
||||
* $this->{$model}->find('metaFieldValue', [
|
||||
* 'AND' => [
|
||||
* ['meta_template_id' => 1, 'field' => 'email', 'value' => '%@domain.test'],
|
||||
* 'OR' => [
|
||||
* ['meta_template_id' => 1, 'field' => 'time_zone', 'value' => 'UTC+1'],
|
||||
* ['meta_template_id' => 1, 'field' => 'time_zone', 'value' => 'UTC+2'],
|
||||
* ],
|
||||
* ],
|
||||
* ])
|
||||
*/
|
||||
public function findMetafieldValue(Query $query, array $filters)
|
||||
{
|
||||
if (empty($filters)) {
|
||||
return $query;
|
||||
}
|
||||
$conjugatedFilters = $this->buildConjugatedFilters($filters);
|
||||
$conditions = $this->buildConjugatedQuerySnippet($conjugatedFilters);
|
||||
$query->where($conditions);
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function buildConjugatedFilters(array $filters): array
|
||||
{
|
||||
$conjugatedFilters = [];
|
||||
foreach ($filters as $operator => $subFilters) {
|
||||
if (is_numeric($operator)) {
|
||||
$conjugatedFilters[] = $subFilters;
|
||||
} else {
|
||||
if (!empty($subFilters)) {
|
||||
$conjugatedFilters[$operator] = $this->buildConjugatedFilters($subFilters);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $conjugatedFilters;
|
||||
}
|
||||
|
||||
protected function buildConjugatedQuerySnippet(array $conjugatedFilters, string $parentOperator='AND'): array
|
||||
{
|
||||
$conditions = [];
|
||||
if (empty($conjugatedFilters['AND']) && empty($conjugatedFilters['OR'])) {
|
||||
if (count(array_filter(array_keys($conjugatedFilters), 'is_string')) > 0) {
|
||||
$conditions = $this->buildComposedQuerySnippet([$conjugatedFilters]);
|
||||
} else {
|
||||
$conditions = $this->buildComposedQuerySnippet($conjugatedFilters, $parentOperator);
|
||||
}
|
||||
} else {
|
||||
foreach ($conjugatedFilters as $subOperator => $subFilter) {
|
||||
$conditions[$subOperator] = $this->buildConjugatedQuerySnippet($subFilter, $subOperator);
|
||||
}
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
public function buildComposedQuerySnippet(array $filters, string $operator='AND'): array
|
||||
{
|
||||
$conditions = [];
|
||||
foreach ($filters as $filterOperator => $filter) {
|
||||
$subQuery = $this->buildQuerySnippet($filter, true);
|
||||
$modelAlias = $this->_table->getAlias();
|
||||
$conditions[$operator][] = [$modelAlias . '.id IN' => $subQuery];
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
|
||||
protected function getQueryExpressionForField(QueryExpression $exp, string $field, string $value)
|
||||
{
|
||||
if (substr($value, 0, 1) == '!') {
|
||||
$value = substr($value, 1);
|
||||
$exp->notEq($field, $value);
|
||||
} else if (strpos($value, '%') != false) {
|
||||
$exp->like($field, $value);
|
||||
} else {
|
||||
$exp->eq($field, $value);
|
||||
}
|
||||
return $exp;
|
||||
}
|
||||
|
||||
protected function buildQuerySnippet(array $filter)
|
||||
{
|
||||
$whereClosure = function (QueryExpression $exp) use ($filter) {
|
||||
foreach ($filter as $column => $value) {
|
||||
$keyedColumn = 'MetaFields.' . $column;
|
||||
$this->getQueryExpressionForField($exp, $keyedColumn, $value);
|
||||
}
|
||||
return $exp;
|
||||
};
|
||||
|
||||
$foreignKey = $this->getConfig('modelAssoc.foreignKey');
|
||||
$query = $this->_table->MetaFields->find()
|
||||
->select('MetaFields.' . $foreignKey)
|
||||
->where($whereClosure);
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,8 @@ class Individual extends AppModel
|
|||
'uuid' => true,
|
||||
];
|
||||
|
||||
protected $_virtual = ['full_name'];
|
||||
// protected $_virtual = ['full_name', 'meta_fields', 'alternate_emails'];
|
||||
protected $_virtual = ['full_name', 'alternate_emails'];
|
||||
|
||||
protected function _getFullName()
|
||||
{
|
||||
|
@ -26,4 +27,38 @@ class Individual extends AppModel
|
|||
}
|
||||
return sprintf("%s %s", $this->first_name, $this->last_name);
|
||||
}
|
||||
|
||||
// protected function _getMetaFields()
|
||||
// {
|
||||
// if (!empty($this->metaTemplates)) {
|
||||
// $metaFields = [];
|
||||
// foreach ($this->metaTemplates as $metaTemplate) {
|
||||
// if (!empty($metaTemplate['meta_template_fields'])) {
|
||||
// foreach ($metaTemplate['meta_template_fields'] as $templateMetaFields) {
|
||||
// foreach ($templateMetaFields['meta_fields'] as $metaField) {
|
||||
// $tmpMetaTemplate = $metaTemplate->toArray();
|
||||
// unset($tmpMetaTemplate['meta_template_fields']);
|
||||
// $metaField['metaTemplate'] = $tmpMetaTemplate;
|
||||
// $metaFields[] = $metaField;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return $metaFields;
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
protected function _getAlternateEmails()
|
||||
{
|
||||
$emails = [];
|
||||
if (!empty($this->meta_fields)) {
|
||||
foreach ($this->meta_fields as $metaField) {
|
||||
if (str_contains($metaField->field, 'email')) {
|
||||
$emails[] = $metaField;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $emails;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ class IndividualsTable extends AppTable
|
|||
$this->addBehavior('UUID');
|
||||
$this->addBehavior('Timestamp');
|
||||
$this->addBehavior('Tags.Tag');
|
||||
$this->addBehavior('MetaFields');
|
||||
|
||||
$this->hasMany(
|
||||
'Alignments',
|
||||
[
|
||||
|
@ -36,16 +38,8 @@ class IndividualsTable extends AppTable
|
|||
$this->belongsToMany('Organisations', [
|
||||
'through' => 'Alignments',
|
||||
]);
|
||||
|
||||
$this->hasMany('MetaFields')
|
||||
->setForeignKey('parent_id')
|
||||
->setBindingKey('id')
|
||||
->setConditions([
|
||||
'MetaFields.scope' => 'individual'
|
||||
])
|
||||
->setDependent(true);
|
||||
|
||||
$this->belongsToMany('MailingLists');
|
||||
|
||||
$this->setDisplayField('email');
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ class MetaFieldsTable extends AppTable
|
|||
$this->setDisplayField('field');
|
||||
$this->belongsTo('MetaTemplates');
|
||||
$this->belongsTo('MetaTemplateFields');
|
||||
$this->belongsTo('Individuals')
|
||||
->setForeignKey('parent_id')
|
||||
->setBindingKey('id')
|
||||
->setConditions([
|
||||
'scope' => 'individual'
|
||||
]);
|
||||
// $this->belongsTo('Individuals')
|
||||
// ->setForeignKey('parent_id')
|
||||
// ->setBindingKey('id')
|
||||
// ->setConditions([
|
||||
// 'scope' => 'individual'
|
||||
// ]);
|
||||
}
|
||||
|
||||
public function validationDefault(Validator $validator): Validator
|
||||
|
|
|
@ -313,7 +313,7 @@ class BootstrapTabs extends BootstrapGeneric
|
|||
$this->bsClasses['nav'][] = 'nav-justify';
|
||||
}
|
||||
|
||||
$activeTab = 0;
|
||||
$activeTab = array_key_first($this->data['navs']);
|
||||
foreach ($this->data['navs'] as $i => $nav) {
|
||||
if (!is_array($nav)) {
|
||||
$this->data['navs'][$i] = ['text' => $nav];
|
||||
|
@ -862,7 +862,7 @@ class BoostrapButton extends BootstrapGeneric {
|
|||
function __construct($options) {
|
||||
$this->allowedOptionValues = [
|
||||
'variant' => array_merge(BootstrapGeneric::$variants, ['link', 'text']),
|
||||
'size' => ['', 'sm', 'lg'],
|
||||
'size' => ['', 'xs', 'sm', 'lg'],
|
||||
'type' => ['button', 'submit', 'reset']
|
||||
];
|
||||
if (empty($options['class'])) {
|
||||
|
@ -877,6 +877,10 @@ class BoostrapButton extends BootstrapGeneric {
|
|||
$this->options = array_merge($this->defaultOptions, $options);
|
||||
$this->checkOptionValidity();
|
||||
|
||||
if (!empty($this->options['id'])) {
|
||||
$this->options['params']['id'] = $this->options['id'];
|
||||
}
|
||||
|
||||
$this->bsClasses[] = 'btn';
|
||||
if ($this->options['outline']) {
|
||||
$this->bsClasses[] = "btn-outline-{$this->options['variant']}";
|
||||
|
|
|
@ -129,6 +129,11 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
|||
'sort' => 'namespace',
|
||||
'data_path' => 'namespace',
|
||||
],
|
||||
[
|
||||
'name' => __('Version'),
|
||||
'sort' => 'version',
|
||||
'data_path' => 'version',
|
||||
],
|
||||
[
|
||||
'name' => __('UUID'),
|
||||
'sort' => 'uuid',
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
$fieldTemplate = $fieldData['type'] . 'Field';
|
||||
}
|
||||
if (empty($fieldData['label'])) {
|
||||
$fieldData['label'] = \Cake\Utility\Inflector::humanize($fieldData['field']);
|
||||
if (!isset($fieldData['label']) || $fieldData['label'] !== false) {
|
||||
$fieldData['label'] = \Cake\Utility\Inflector::humanize($fieldData['field']);
|
||||
}
|
||||
}
|
||||
if (!empty($fieldDesc[$fieldData['field']])) {
|
||||
$fieldData['label'] .= $this->element(
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<div class="col-12 mb-3">
|
||||
<h2 class="fw-light">
|
||||
<?= empty($data['title']) ? sprintf('%s %s', $actionName, $modelName) : h($data['title']) ?>
|
||||
</h2>
|
||||
<?= $formCreate ?>
|
||||
<?= $ajaxFlashMessage ?>
|
||||
<?php if (!empty($data['description'])) : ?>
|
||||
<div class="pb-3 fw-light">
|
||||
<?= $data['description'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="panel col-8">
|
||||
<?= $fieldsString ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($metaTemplateString)) : ?>
|
||||
<div class="col-10">
|
||||
<?=
|
||||
$this->Bootstrap->accordion(
|
||||
[
|
||||
'class' => 'mb-3'
|
||||
],
|
||||
[
|
||||
[
|
||||
'_open' => true,
|
||||
'header' => [
|
||||
'title' => __('Meta fields')
|
||||
],
|
||||
'body' => $metaTemplateString,
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?= $this->element('genericElements/Form/submitButton', $submitButtonData); ?>
|
||||
<?= $formEnd; ?>
|
||||
</div>
|
|
@ -0,0 +1,28 @@
|
|||
<?php if (!empty($data['description'])) : ?>
|
||||
<div class="pb-3 fw-light">
|
||||
<?= $data['description'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?= $ajaxFlashMessage ?>
|
||||
<?= $formCreate ?>
|
||||
<?= $fieldsString ?>
|
||||
|
||||
<?php if (!empty($metaTemplateString)) : ?>
|
||||
<?=
|
||||
$this->Bootstrap->accordion(
|
||||
[
|
||||
'class' => 'mb-3'
|
||||
],
|
||||
[
|
||||
[
|
||||
'_open' => true,
|
||||
'header' => [
|
||||
'title' => __('Meta fields')
|
||||
],
|
||||
'body' => $metaTemplateString,
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
<?= $formEnd; ?>
|
|
@ -107,91 +107,35 @@
|
|||
$seedModal = 'mseed-' . mt_rand();
|
||||
echo $this->element('genericElements/genericModal', [
|
||||
'title' => empty($data['title']) ? sprintf('%s %s', $actionName, $modelName) : h($data['title']),
|
||||
'body' => sprintf(
|
||||
'%s%s%s%s%s%s',
|
||||
empty($data['description']) ? '' : sprintf(
|
||||
'<div class="pb-2 fw-light">%s</div>',
|
||||
$data['description']
|
||||
),
|
||||
$ajaxFlashMessage,
|
||||
$formCreate,
|
||||
$fieldsString,
|
||||
empty($metaTemplateString) ? '' : $this->Bootstrap->accordion(
|
||||
[
|
||||
'class' => 'mb-2'
|
||||
],
|
||||
[
|
||||
[
|
||||
'_open' => true,
|
||||
'header' => [
|
||||
'title' => __('Meta fields')
|
||||
],
|
||||
'body' => $metaTemplateString,
|
||||
],
|
||||
]
|
||||
),
|
||||
$formEnd
|
||||
),
|
||||
'body' => $this->element('genericElements/Form/formLayouts/formRaw', [
|
||||
'formCreate' => $formCreate,
|
||||
'ajaxFlashMessage' => $ajaxFlashMessage,
|
||||
'fieldsString' => $fieldsString,
|
||||
'formEnd' => $formEnd,
|
||||
'metaTemplateString' => $metaTemplateString,
|
||||
]),
|
||||
'actionButton' => $this->element('genericElements/Form/submitButton', $submitButtonData),
|
||||
'class' => "modal-lg {$seedModal}"
|
||||
]);
|
||||
} else if (!empty($raw)) {
|
||||
echo sprintf(
|
||||
'%s%s%s%s%s%s',
|
||||
empty($data['description']) ? '' : sprintf(
|
||||
'<div class="pb-2">%s</div>',
|
||||
$data['description']
|
||||
),
|
||||
$ajaxFlashMessage,
|
||||
$formCreate,
|
||||
$fieldsString,
|
||||
empty($metaTemplateString) ? '' : $this->Bootstrap->accordion(
|
||||
[
|
||||
'class' => 'mb-2'
|
||||
],
|
||||
[
|
||||
[
|
||||
'_open' => true,
|
||||
'header' => [
|
||||
'title' => __('Meta fields')
|
||||
],
|
||||
'body' => $metaTemplateString,
|
||||
],
|
||||
]
|
||||
),
|
||||
$formEnd
|
||||
);
|
||||
echo $this->element('genericElements/Form/formLayouts/formDefault', [
|
||||
'formCreate' => $formCreate,
|
||||
'ajaxFlashMessage' => $ajaxFlashMessage,
|
||||
'fieldsString' => $fieldsString,
|
||||
'formEnd' => $formEnd,
|
||||
'metaTemplateString' => $metaTemplateString,
|
||||
]);
|
||||
} else {
|
||||
echo sprintf(
|
||||
'%s<h2 class="fw-light">%s</h2>%s%s%s%s%s%s%s%s%s',
|
||||
empty($ajax) ? '<div class="col-8">' : '',
|
||||
empty($data['title']) ? sprintf('%s %s', $actionName, $modelName) : h($data['title']),
|
||||
$formCreate,
|
||||
$ajaxFlashMessage,
|
||||
empty($data['description']) ? '' : sprintf(
|
||||
'<div class="pb-3 fw-light">%s</div>',
|
||||
$data['description']
|
||||
),
|
||||
sprintf('<div class="panel">%s</div>', $fieldsString),
|
||||
empty($metaTemplateString) ? '' : $this->Bootstrap->accordion(
|
||||
[
|
||||
'class' => 'mb-2'
|
||||
],
|
||||
[
|
||||
[
|
||||
'_open' => true,
|
||||
'header' => [
|
||||
'title' => __('Meta fields')
|
||||
],
|
||||
'body' => $metaTemplateString,
|
||||
],
|
||||
]
|
||||
),
|
||||
$this->element('genericElements/Form/submitButton', $submitButtonData),
|
||||
$formEnd,
|
||||
'<br /><br />',
|
||||
empty($ajax) ? '</div>' : ''
|
||||
);
|
||||
echo $this->element('genericElements/Form/formLayouts/formDefault', [
|
||||
'actionName' => $actionName,
|
||||
'modelName' => $modelName,
|
||||
'submitButtonData' => $submitButtonData,
|
||||
'formCreate' => $formCreate,
|
||||
'ajaxFlashMessage' => $ajaxFlashMessage,
|
||||
'fieldsString' => $fieldsString,
|
||||
'formEnd' => $formEnd,
|
||||
'metaTemplateString' => $metaTemplateString,
|
||||
]);
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
<?php
|
||||
|
||||
use Cake\Utility\Inflector;
|
||||
|
||||
$default_template = [
|
||||
'inputContainer' => '<div class="row mb-3 metafield-container">{{content}}</div>',
|
||||
'inputContainerError' => '<div class="row mb-3 metafield-container has-error">{{content}}</div>',
|
||||
'formGroup' => '<div class="col-sm-2 form-label" {{attrs}}>{{label}}</div><div class="col-sm-10">{{input}}{{error}}</div>',
|
||||
];
|
||||
$this->Form->setTemplates($default_template);
|
||||
$backupTemplates = $this->Form->getTemplates();
|
||||
$tabData = [];
|
||||
foreach($metaTemplatesData as $i => $metaTemplate) {
|
||||
foreach ($metaTemplatesData as $i => $metaTemplate) {
|
||||
if ($metaTemplate->is_default) {
|
||||
$tabData['navs'][$i] = [
|
||||
'html' => $this->element('/genericElements/MetaTemplates/metaTemplateNav', ['metaTemplate' => $metaTemplate])
|
||||
|
@ -13,20 +21,53 @@ foreach($metaTemplatesData as $i => $metaTemplate) {
|
|||
];
|
||||
}
|
||||
$fieldsHtml = '';
|
||||
foreach ($metaTemplate->meta_template_fields as $metaField) {
|
||||
$metaField->label = Inflector::humanize($metaField->field);
|
||||
$metaField->field = sprintf('%s.%s.%s', 'metaFields', $metaField->meta_template_id, $metaField->field);
|
||||
$fieldsHtml .= $this->element(
|
||||
'genericElements/Form/fieldScaffold', [
|
||||
'fieldData' => $metaField->toArray(),
|
||||
'form' => $this->Form
|
||||
]
|
||||
);
|
||||
foreach ($metaTemplate->meta_template_fields as $metaTemplateField) {
|
||||
$metaTemplateField->label = Inflector::humanize($metaTemplateField->field);
|
||||
if (!empty($metaTemplateField->metaFields)) {
|
||||
if (!empty($metaTemplateField->multiple)) {
|
||||
$fieldsHtml .= $this->element(
|
||||
'genericElements/Form/multiFieldScaffold',
|
||||
[
|
||||
'metaFieldsEntities' => $metaTemplateField->metaFields,
|
||||
'metaTemplateField' => $metaTemplateField,
|
||||
'multiple' => !empty($metaTemplateField->multiple),
|
||||
'form' => $this->Form,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$metaField = reset($metaTemplateField->metaFields);
|
||||
$fieldData = [
|
||||
'field' => sprintf('MetaTemplates.%s.meta_template_fields.%s.metaFields.%s.value', $metaField->meta_template_id, $metaField->meta_template_field_id, $metaField->id),
|
||||
'label' => $metaTemplateField->field,
|
||||
];
|
||||
$fieldsHtml .= $this->element(
|
||||
'genericElements/Form/fieldScaffold',
|
||||
[
|
||||
'fieldData' => $fieldData,
|
||||
'metaTemplateField' => $metaTemplateField,
|
||||
'form' => $this->Form
|
||||
]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->Form->setTemplates($backupTemplates);
|
||||
$fieldData = [
|
||||
'field' => sprintf('MetaTemplates.%s.meta_template_fields.%s.metaFields.new.0', $metaTemplateField->meta_template_id, $metaTemplateField->id),
|
||||
'label' => $metaTemplateField->field,
|
||||
];
|
||||
$fieldsHtml .= $this->element(
|
||||
'genericElements/Form/fieldScaffold',
|
||||
[
|
||||
'fieldData' => $fieldData,
|
||||
'form' => $this->Form
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
$tabData['content'][$i] = $fieldsHtml;
|
||||
}
|
||||
echo $this->Bootstrap->Tabs([
|
||||
'pills' => true,
|
||||
'data' => $tabData,
|
||||
'nav-class' => ['pb-1']
|
||||
]);
|
||||
'nav-class' => ['mb-3']
|
||||
]);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
$seed = 'mfb-' . mt_rand();
|
||||
?>
|
||||
<div class="d-flex align-items-center">
|
||||
<?php
|
||||
// $content = sprintf('<a class="btn btn-primary btn-xs">%s</a><a class="btn btn-link btn-xs">%s</a>', $this->Bootstrap->icon('plus'), __('Add another {0}', h($fieldData['label'])));
|
||||
$content = sprintf('<a class="btn btn-primary btn-xs">%s</a><a class="btn btn-link btn-xs">%s</a>', $this->Bootstrap->icon('plus'), __('Add another {0}', h($metaTemplateFieldName)));
|
||||
$content = sprintf(
|
||||
'%s%s',
|
||||
$this->Bootstrap->button([
|
||||
'nodeType' => 'a',
|
||||
'icon' => 'plus',
|
||||
'variant' => 'secondary',
|
||||
'size' => 'xs',
|
||||
]),
|
||||
$this->Bootstrap->button([
|
||||
'nodeType' => 'a',
|
||||
// 'text' => __('Add another {0}', h($fieldData['label'])),
|
||||
'text' => __('Add another {0}', h($metaTemplateFieldName)),
|
||||
'variant' => 'link',
|
||||
'class' => ['link-secondary'],
|
||||
'size' => 'xs',
|
||||
])
|
||||
);
|
||||
?>
|
||||
<?=
|
||||
$this->Bootstrap->button([
|
||||
'id' => $seed,
|
||||
'html' => $content,
|
||||
'variant' => 'link',
|
||||
'size' => 'xs',
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
$('#<?= $seed ?>').click(addNewField)
|
||||
|
||||
function addNewField() {
|
||||
const $clicked = $(this);
|
||||
const $lastInputContainer = $clicked.closest('.multi-metafields-container').children().not('.template-container').find('input').last().closest('.multi-metafield-container')
|
||||
const $templateContainer = $clicked.closest('.multi-metafields-container').find('.template-container').children()
|
||||
const $clonedContainer = $templateContainer.clone()
|
||||
$clonedContainer.removeClass('d-none', 'template-container')
|
||||
const $clonedInput = $clonedContainer.find('input, select')
|
||||
if ($clonedInput.length > 0) {
|
||||
const injectedTemplateId = $clicked.closest('.multi-metafields-container').find('.new-metafield').length
|
||||
$clonedInput.addClass('new-metafield')
|
||||
adjustClonedInputAttr($clonedInput, injectedTemplateId)
|
||||
$clonedContainer.insertAfter($lastInputContainer)
|
||||
}
|
||||
}
|
||||
|
||||
function adjustClonedInputAttr($input, injectedTemplateId) {
|
||||
let explodedPath = $input.attr('field').split('.').splice(0, 5)
|
||||
explodedPath.push('new', injectedTemplateId)
|
||||
dottedPathStr = explodedPath.join('.')
|
||||
brackettedPathStr = explodedPath.map((elem, i) => {
|
||||
return i == 0 ? elem : `[${elem}]`
|
||||
}).join('')
|
||||
$input.attr('id', dottedPathStr)
|
||||
.attr('field', dottedPathStr)
|
||||
.attr('name', brackettedPathStr)
|
||||
.val('')
|
||||
}
|
||||
})()
|
||||
</script>
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
if (!empty($metaTemplateField)) {
|
||||
$fieldData = [
|
||||
'label' => false,
|
||||
'field' => sprintf('MetaTemplates.%s.meta_template_fields.%s.{count}', $metaTemplateField['meta_template_id'], $metaTemplateField['id']),
|
||||
'class' => 'metafield-template',
|
||||
];
|
||||
echo $this->element(
|
||||
'genericElements/Form/fieldScaffold',
|
||||
[
|
||||
'fieldData' => $fieldData,
|
||||
'form' => $form
|
||||
]
|
||||
);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
$default_template = [
|
||||
'inputContainer' => '<div class="row pb-1 multi-metafield-container">{{content}}</div>',
|
||||
'inputContainerError' => '<div class="row pb-1 metafield-container has-error">{{content}}</div>',
|
||||
'formGroup' => '<div class="col-sm-2 form-label" {{attrs}}>{{label}}</div><div class="col-sm-10">{{input}}{{error}}</div>',
|
||||
];
|
||||
$form->setTemplates($default_template);
|
||||
|
||||
$fieldsHtml = '';
|
||||
$labelPrintedOnce = false;
|
||||
foreach ($metaFieldsEntities as $i => $metaFieldsEntity) {
|
||||
$fieldData = [
|
||||
'label' => $metaFieldsEntity->field,
|
||||
'field' => sprintf('MetaTemplates.%s.meta_template_fields.%s.metaFields.%s.value', $metaFieldsEntity->meta_template_id, $metaFieldsEntity->meta_template_field_id, $metaFieldsEntity->id),
|
||||
];
|
||||
if ($labelPrintedOnce) { // Only the first input can have a label
|
||||
$fieldData['label'] = false;
|
||||
}
|
||||
$labelPrintedOnce = true;
|
||||
$fieldsHtml .= $this->element(
|
||||
'genericElements/Form/fieldScaffold',
|
||||
[
|
||||
'fieldData' => $fieldData,
|
||||
'form' => $form
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!empty($metaTemplateField) && !empty($multiple)) { // Add multiple field button
|
||||
$emptyInputForSecurityComponent = $this->element(
|
||||
'genericElements/Form/fieldScaffold',
|
||||
[
|
||||
'fieldData' => [
|
||||
'label' => false,
|
||||
'field' => sprintf('MetaTemplates.%s.meta_template_fields.%s.metaFields.new[]', $metaFieldsEntity->meta_template_id, $metaFieldsEntity->meta_template_field_id),
|
||||
],
|
||||
'form' => $form,
|
||||
]
|
||||
);
|
||||
$multiFieldButtonHtml = sprintf(
|
||||
'<div class="row pb-1 multi-metafield-container"><div class="col-sm-2 form-label"></div><div class="col-sm-10">%s</div></div>',
|
||||
$this->element(
|
||||
'genericElements/Form/multiFieldButton',
|
||||
[
|
||||
'metaTemplateFieldName' => $metaTemplateField->field,
|
||||
]
|
||||
)
|
||||
);
|
||||
$fieldsHtml .= sprintf('<div class="d-none template-container">%s</div>', $emptyInputForSecurityComponent);
|
||||
$fieldsHtml .= $multiFieldButtonHtml;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="row mb-3 multi-metafields-container">
|
||||
<?= $fieldsHtml; ?>
|
||||
</div>
|
|
@ -168,11 +168,3 @@ input[type="checkbox"]:disabled.change-cursor {
|
|||
-webkit-mask-repeat: no-repeat;
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='223.995' width='383.98752' viewBox='0 0 383.98752 223.995' role='img'%3E%3Cpath d='m 367.9975,0 h -118.06 c -21.38,0 -32.09,25.85 -16.97,40.97 l 32.4,32.4 -73.37,73.38 -73.37,-73.37 c -12.5,-12.5 -32.76,-12.5 -45.25,0 l -68.69,68.69 c -6.25,6.25 -6.25,16.38 0,22.63 l 22.62,22.62 c 6.25,6.25 16.38,6.25 22.63,0 l 46.06,-46.07 73.37,73.37 c 12.5,12.5 32.76,12.5 45.25,0 l 96,-96 32.4,32.4 c 15.12,15.12 40.97,4.41 40.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important;
|
||||
}
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important;
|
||||
}
|
|
@ -282,3 +282,39 @@
|
|||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #6c757d;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #444;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
body {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #6c757d;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
body {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #95a5a6;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
body {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #95a5a6;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
body {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
.panel {
|
||||
background-color: transparent;
|
||||
|
|
|
@ -279,6 +279,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #7a8288;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
body {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
|
|
@ -283,6 +283,42 @@
|
|||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%); }
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important; }
|
||||
|
||||
.fs-8 {
|
||||
font-size: .7rem !important; }
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15; }
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); }
|
||||
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative; }
|
||||
:not(.meta-template-container) > .multi-metafield-container > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: #ea39b8;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px; }
|
||||
:not(.meta-template-container) > .multi-metafield-container:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px; }
|
||||
|
||||
/* Body */
|
||||
.panel {
|
||||
background-color: #363636;
|
||||
|
|
|
@ -1 +1,71 @@
|
|||
@import "../bootstrap/scss/bootstrap";
|
||||
$secondary: #6c757d !default;
|
||||
|
||||
// .multi-metafield-container {
|
||||
// position: relative;
|
||||
// }
|
||||
|
||||
// .multi-metafield-container .col-sm-10::before {
|
||||
// transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
// border-style: solid;
|
||||
// border-color: $secondary;
|
||||
// }
|
||||
|
||||
// .multi-metafield-container:first-child .col-sm-10::before {
|
||||
// transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
// border-top-right-radius: 3px;
|
||||
// position: absolute;
|
||||
// content: ' ';
|
||||
// width: 0.5rem;
|
||||
// border-width: 2px 2px 0px 0px;
|
||||
// }
|
||||
|
||||
// .multi-metafield-container .col-sm-10::before {
|
||||
// position: absolute;
|
||||
// content: ' ';
|
||||
// width: 0.5rem;
|
||||
// height: 100%;
|
||||
// border-width: 0px 2px 0px 0px;
|
||||
// }
|
||||
|
||||
// .multi-metafield-container:last-child .col-sm-10::before {
|
||||
// transform: translateX(calc(1.5rem * -.5));
|
||||
// border-bottom-left-radius: 3px;
|
||||
// position: absolute;
|
||||
// content: ' ';
|
||||
// width: 0.5rem;
|
||||
// height: 50%;
|
||||
// border-width: 0px 0px 2px 2px;
|
||||
// }
|
||||
|
||||
// :not(.meta-template-container) .multi-metafield-container {
|
||||
// .multi-metafield-container :not(.meta-template-container) {
|
||||
:not(.meta-template-container) > .multi-metafield-container {
|
||||
position: relative;
|
||||
|
||||
& > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5 - 0.25rem - 2px));
|
||||
border-style: solid;
|
||||
border-color: $secondary;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 0.5rem;
|
||||
height: 100%;
|
||||
border-width: 0px 2px 0px 0px;
|
||||
}
|
||||
|
||||
&:first-child > .col-sm-10::before {
|
||||
transform: translate(calc(1.5rem * -.5 - 0.25rem - 2px), 12px);
|
||||
border-top-right-radius: 3px;
|
||||
border-width: 2px 2px 0px 0px;
|
||||
}
|
||||
|
||||
&:last-child > .col-sm-10::before {
|
||||
transform: translateX(calc(1.5rem * -.5));
|
||||
border-bottom-left-radius: 3px;
|
||||
height: 50%;
|
||||
border-width: 0px 0px 2px 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -164,4 +164,24 @@ $toast-color-level: 70% !default;
|
|||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.fs-7 {
|
||||
font-size: .875rem !important;
|
||||
}
|
||||
.fs-8 {
|
||||
font-size: .7rem !important;
|
||||
}
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.1rem;
|
||||
font-size: 0.7rem;
|
||||
border-radius: 0.15rem;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
|
||||
}
|
||||
|
||||
@import '../../../scss/custom.scss';
|
Loading…
Reference in New Issue