mirror of
https://github.com/jbcr/core.git
synced 2026-04-24 17:18:08 +02:00
Merge branch 'master' of github.com:bolt/core
This commit is contained in:
@@ -1,33 +1,75 @@
|
||||
<template>
|
||||
<div ref="collectionContainer" class="collection-container">
|
||||
<div v-for="element in elements" :key="element.id" class="collection-item">
|
||||
<div :is="element"></div>
|
||||
<div class="expand-buttons">
|
||||
<label>{{ labels.field_label }}:</label>
|
||||
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-secondary btn-sm collection-expand-all">
|
||||
<i class="fas fa-fw fa-expand-alt"></i>
|
||||
{{ labels.expand_all }}
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm collection-collapse-all">
|
||||
<i class="fas fa-fw fa-compress-alt"></i>
|
||||
{{ labels.collapse_all }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
<editor-select
|
||||
ref="templateSelect"
|
||||
class="flex-grow-1 mr-2"
|
||||
:value="initialSelectValue"
|
||||
:name="templateSelectName"
|
||||
:options="templateSelectOptions"
|
||||
:allowempty="false"
|
||||
></editor-select>
|
||||
<div
|
||||
v-for="element in existingFields"
|
||||
:key="element.hash"
|
||||
class="collection-item"
|
||||
>
|
||||
<details :open="state === 'expanded'">
|
||||
<summary>
|
||||
<!-- Initial title. This is replaced by dynamic title in JS below. -->
|
||||
<div class="collection-item-title" :data-label="element.label">
|
||||
<i :class="[element.icon, 'fas fa-fw']" />
|
||||
{{ element.label }}
|
||||
</div>
|
||||
|
||||
<!-- Navigation buttons -->
|
||||
<div :is="compile(element.buttons)"></div>
|
||||
</summary>
|
||||
|
||||
<!-- The actual field -->
|
||||
<div :is="compile(element.content)"></div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<small>{{ labels.select_tooltip }}</small>
|
||||
|
||||
<div class="dropdown">
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
id="dropdownMenuButton"
|
||||
:disabled="!allowMore"
|
||||
@click="addCollectionItem"
|
||||
class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i class="fas fa-fw fa-plus"></i>
|
||||
{{ labels.add_collection_item }}
|
||||
<i class="fas fa-fw fa-plus"></i> {{ labels.add_collection_item }}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<a
|
||||
v-for="template in templates"
|
||||
:key="template.label"
|
||||
class="dropdown-item"
|
||||
:data-template="template.label"
|
||||
@click="addCollectionItem($event)"
|
||||
>
|
||||
<i :class="[template.icon, 'fas fa-fw']" />
|
||||
{{ template.label }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import $ from 'jquery';
|
||||
var uniqid = require('locutus/php/misc/uniqid');
|
||||
|
||||
export default {
|
||||
@@ -48,25 +90,17 @@ export default {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
state: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
let elements = [];
|
||||
this.existingFields.forEach(function(field) {
|
||||
elements.push(Vue.compile(field.html));
|
||||
});
|
||||
|
||||
let templateSelectOptions = [];
|
||||
|
||||
this.templates.forEach(function(template) {
|
||||
templateSelectOptions.push({
|
||||
key: template.label,
|
||||
value: template.label,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
elements: elements,
|
||||
counter: elements.length,
|
||||
elements: this.existingFields,
|
||||
counter: this.existingFields.length,
|
||||
templateSelectName: 'templateSelect' + this.id,
|
||||
templateSelectOptions: templateSelectOptions,
|
||||
selector: {
|
||||
@@ -75,6 +109,9 @@ export default {
|
||||
remove: '.action-remove-collection-item',
|
||||
moveUp: '.action-move-up-collection-item',
|
||||
moveDown: '.action-move-down-collection-item',
|
||||
expandAll: '.collection-expand-all',
|
||||
collapseAll: '.collection-collapse-all',
|
||||
editor: '#editor',
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -87,11 +124,13 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setAllButtonsStates(window.$(this.$refs.collectionContainer));
|
||||
let vueThis = this;
|
||||
/*
|
||||
** Event listeners on collection items buttons
|
||||
** This is a jQuery event listener, because Vue cannot handle an event emitted by a non-vue element.
|
||||
** The collection items are not Vue elements in order to initialise them correctly within their twig template.
|
||||
|
||||
/**
|
||||
* Event listeners on collection items buttons
|
||||
* This is a jQuery event listener, because Vue cannot handle an event emitted by a non-vue element.
|
||||
* The collection items are not Vue elements in order to initialise them correctly within their twig template.
|
||||
*/
|
||||
window.$(document).on('click', vueThis.selector.remove, function(e) {
|
||||
e.preventDefault();
|
||||
@@ -126,11 +165,76 @@ export default {
|
||||
vueThis.setButtonsState(thisCollectionItem);
|
||||
vueThis.setButtonsState(nextCollectionItem);
|
||||
});
|
||||
|
||||
window.$(document).on('click', vueThis.selector.expandAll, function(e) {
|
||||
e.preventDefault();
|
||||
const collection = $(e.target).closest(
|
||||
vueThis.selector.collectionContainer,
|
||||
);
|
||||
collection.find('details').attr('open', '');
|
||||
});
|
||||
|
||||
window.$(document).on('click', vueThis.selector.collapseAll, function(e) {
|
||||
e.preventDefault();
|
||||
const collection = $(e.target).closest(
|
||||
vueThis.selector.collectionContainer,
|
||||
);
|
||||
collection.find('details').removeAttr('open');
|
||||
});
|
||||
|
||||
/**
|
||||
* Update the title dynamically.
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
$.each(window.$(vueThis.selector.item), function() {
|
||||
updateTitle(this);
|
||||
});
|
||||
|
||||
window
|
||||
.$(vueThis.selector.editor)
|
||||
.on('keyup change', vueThis.selector.item, function() {
|
||||
updateTitle(this);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Pass a .collection-item element to update the title
|
||||
* with the value of the first text-based field.
|
||||
*/
|
||||
function updateTitle(item) {
|
||||
const label = $(item)
|
||||
.find('.collection-item-title')
|
||||
.first();
|
||||
const icon = label
|
||||
.find('i')
|
||||
.first()
|
||||
.get(0).outerHTML;
|
||||
const input = $(item)
|
||||
.find('textarea,input[type="text"]')
|
||||
.first();
|
||||
const title = $(input).val() ? $(input).val() : label.attr('data-label');
|
||||
label.html(icon + title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open newly inserted collection items.
|
||||
*/
|
||||
$(document).on('DOMNodeInserted', function(e) {
|
||||
if ($(e.target).hasClass('collection-item')) {
|
||||
$(e.target)
|
||||
.find('details')
|
||||
.first()
|
||||
.attr('open', '');
|
||||
}
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
this.setAllButtonsStates(window.$(this.$refs.collectionContainer));
|
||||
},
|
||||
methods: {
|
||||
compile(element) {
|
||||
return Vue.compile(element);
|
||||
},
|
||||
setAllButtonsStates(collectionContainer) {
|
||||
let vueThis = this;
|
||||
collectionContainer.children(vueThis.selector.item).each(function() {
|
||||
@@ -180,26 +284,29 @@ export default {
|
||||
.closest('.collection-item')
|
||||
.last();
|
||||
},
|
||||
addCollectionItem() {
|
||||
let template = this.getSelectedTemplate();
|
||||
addCollectionItem(event) {
|
||||
// duplicate template without reference
|
||||
let template = $.extend(true, {}, this.getSelectedTemplate(event));
|
||||
|
||||
let html = template.html.replace(
|
||||
const realhash = uniqid();
|
||||
|
||||
template.content = template.content.replace(
|
||||
new RegExp(template.hash, 'g'),
|
||||
uniqid(),
|
||||
realhash,
|
||||
);
|
||||
let res = Vue.compile(html);
|
||||
this.elements.push(res);
|
||||
|
||||
template.hash = realhash;
|
||||
|
||||
this.elements.push(template);
|
||||
this.counter++;
|
||||
},
|
||||
getSelectedTemplate() {
|
||||
let selectValue = this.$refs.templateSelect.selected;
|
||||
if (Array.isArray(selectValue)) {
|
||||
selectValue = selectValue[0];
|
||||
}
|
||||
getSelectedTemplate(event) {
|
||||
const target = $(event.target).attr('data-template')
|
||||
? $(event.target)
|
||||
: $(event.target).closest('[data-template]');
|
||||
let selectValue = target.attr('data-template');
|
||||
|
||||
return this.templates.find(
|
||||
template => template.label === selectValue.key,
|
||||
);
|
||||
return this.templates.find(template => template.label === selectValue);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -8,10 +8,16 @@
|
||||
<img
|
||||
src="/assets/images/bolt_logo_dashboard.svg"
|
||||
alt="⚙️ Bolt"
|
||||
height="28"
|
||||
height="26"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-item toolbar-item__site">
|
||||
<a href="/" target="_blank">
|
||||
<i class="fas fa-sign-out-alt"></i>{{ labels['action.view_site'] }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form
|
||||
:action="backendPrefix"
|
||||
class="toolbar-item toolbar-item__filter input-group"
|
||||
@@ -25,41 +31,16 @@
|
||||
:value="filterValue"
|
||||
/>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-tertiary" type="submit">
|
||||
<i class="fas fa-search"></i>{{ labels['listing.button_search'] }}
|
||||
<button
|
||||
class="btn btn-tertiary"
|
||||
type="submit"
|
||||
:title="labels['listing.button_search']"
|
||||
>
|
||||
<i class="fas fa-search" style="margin: 0;"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="toolbar-item toolbar-item__site">
|
||||
<a href="/" target="_blank">
|
||||
<i class="fas fa-sign-out-alt"></i>{{ labels['action.view_site'] }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-item btn-group toolbar-item__new">
|
||||
<button
|
||||
class="btn new-item__dropdown-toggler dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
data-display="static"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i class="fas fa-magic"></i>{{ labels['action.create_new'] }}…
|
||||
</button>
|
||||
<div class="new-item__dropdown dropdown-menu">
|
||||
<ul>
|
||||
<li v-for="(item, index) in createMenu" :key="index">
|
||||
<a :href="item.link_new"
|
||||
><i :class="`fa fa-fw ${item.icon}`"></i>
|
||||
{{ item.singular_name }}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-item btn-group toolbar-item__profile">
|
||||
<button
|
||||
class="btn user profile__dropdown-toggler dropdown-toggle"
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.875rem;
|
||||
padding: 0;
|
||||
|
||||
a {
|
||||
font-size: 0.9375rem;
|
||||
@@ -119,15 +118,7 @@
|
||||
|
||||
&__brand {
|
||||
justify-content: left;
|
||||
padding-left: 2rem;
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
flex: 0 1 $admin-sidebar-width;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(wd) {
|
||||
flex: 0 1 $admin-sidebar-width-wide;
|
||||
}
|
||||
padding: 0 2rem;
|
||||
|
||||
svg,
|
||||
img {
|
||||
@@ -152,7 +143,7 @@
|
||||
|
||||
&__filter {
|
||||
margin-left: auto;
|
||||
max-width: 400px;
|
||||
max-width: 200px;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
@@ -161,6 +152,7 @@
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
display: block;
|
||||
padding-top: 0.1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//** Fields | Collection
|
||||
|
||||
.collection-container {
|
||||
.expand-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
.btn-group {
|
||||
height: min-content;
|
||||
}
|
||||
}
|
||||
|
||||
.collection-item {
|
||||
summary {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "►";
|
||||
vertical-align: 25%; // middle of line
|
||||
margin-right: 0.5rem;
|
||||
width: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
details[open] summary::before {
|
||||
content: "▼";
|
||||
}
|
||||
|
||||
.collection-item-title {
|
||||
display: inline-block;
|
||||
max-width: 40%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,4 @@
|
||||
@import '_file';
|
||||
@import '_pre_postfix';
|
||||
@import '_multiselect';
|
||||
@import '_collection';
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.showTimeInput.hasTime {
|
||||
&.hasTime {
|
||||
.flatpickr-time {
|
||||
height: $timeHeight;
|
||||
border-top: 1px solid $calendarBorderColor;
|
||||
|
||||
+23
-23
@@ -38,32 +38,32 @@
|
||||
"sensiolabs/security-checker": "^6.0",
|
||||
"siriusphp/upload": "^3.0.1",
|
||||
"squirrelphp/twig-php-syntax": "^1.5",
|
||||
"symfony/asset": "^4.4 | ^5.1",
|
||||
"symfony/console": "^4.4 | ^5.1",
|
||||
"symfony/debug-bundle": "^4.4 | ^5.1",
|
||||
"symfony/dependency-injection": "^4.4 | ^5.1",
|
||||
"symfony/dotenv": "^4.4 | ^5.1",
|
||||
"symfony/expression-language": "^4.4 | ^5.1",
|
||||
"symfony/asset": "^5.1",
|
||||
"symfony/console": "^5.1",
|
||||
"symfony/debug-bundle": "^5.1",
|
||||
"symfony/dependency-injection": "^5.1",
|
||||
"symfony/dotenv": "^5.1",
|
||||
"symfony/expression-language": "^5.1",
|
||||
"symfony/flex": "^1.9",
|
||||
"symfony/form": "^4.4 | ^5.1",
|
||||
"symfony/framework-bundle": "^4.4 | ^5.1",
|
||||
"symfony/http-client": "^4.4 | ^5.1",
|
||||
"symfony/mailer": "^4.4 | ^5.1",
|
||||
"symfony/form": "^5.1",
|
||||
"symfony/framework-bundle": "^5.1",
|
||||
"symfony/http-client": "^5.1",
|
||||
"symfony/mailer": "^5.1",
|
||||
"symfony/maker-bundle": "^1.14",
|
||||
"symfony/monolog-bridge": "^4.4 | ^5.1",
|
||||
"symfony/monolog-bridge": "^5.1",
|
||||
"symfony/monolog-bundle": "^3.5",
|
||||
"symfony/polyfill-php72": "^1.13",
|
||||
"symfony/security-bundle": "^4.4 | ^5.1",
|
||||
"symfony/serializer": "^4.4 | ^5.1",
|
||||
"symfony/stopwatch": "^4.4 | ^5.1",
|
||||
"symfony/translation": "^4.4 | ^5.1",
|
||||
"symfony/twig-bundle": "^4.4 | ^5.1",
|
||||
"symfony/validator": "^4.4 | ^5.1",
|
||||
"symfony/var-dumper": "^4.4 | ^5.1",
|
||||
"symfony/web-profiler-bundle": "^4.4 | ^5.1",
|
||||
"symfony/security-bundle": "^5.1",
|
||||
"symfony/serializer": "^5.1",
|
||||
"symfony/stopwatch": "^5.1",
|
||||
"symfony/translation": "^5.1",
|
||||
"symfony/twig-bundle": "^5.1",
|
||||
"symfony/validator": "^5.1",
|
||||
"symfony/var-dumper": "^5.1",
|
||||
"symfony/web-profiler-bundle": "^5.1",
|
||||
"symfony/web-server-bundle": "^4.4",
|
||||
"symfony/webpack-encore-bundle": "^1.7",
|
||||
"symfony/yaml": "^4.4 | ^5.1",
|
||||
"symfony/yaml": "^5.1",
|
||||
"tightenco/collect": "^7.25",
|
||||
"twig/twig": "^3.0",
|
||||
"ua-parser/uap-php": "^3.9",
|
||||
@@ -102,8 +102,8 @@
|
||||
"phpunit/phpunit": "^7.5",
|
||||
"roave/security-advisories": "dev-master@dev",
|
||||
"se/selenium-server-standalone": "^3.141",
|
||||
"symfony/browser-kit": "^4.4 | ^5.1",
|
||||
"symfony/css-selector": "^4.4 | ^5.1",
|
||||
"symfony/browser-kit": "^5.1",
|
||||
"symfony/css-selector": "^5.1",
|
||||
"symplify/easy-coding-standard": "^8.2.3",
|
||||
"vaimo/binary-chromedriver": "^5.0"
|
||||
},
|
||||
@@ -116,7 +116,7 @@
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": true,
|
||||
"require": "^4.4 | ^5.1"
|
||||
"require": "^5.1"
|
||||
},
|
||||
"public-dir": "public"
|
||||
},
|
||||
|
||||
@@ -174,6 +174,7 @@ showcases:
|
||||
error: "The Title field is required, and must contain at least 2 characters"
|
||||
placeholder: "Placeholder for the title"
|
||||
group: Text
|
||||
fixture_format: '{name}'
|
||||
postfix: |
|
||||
This is an example of a longer "postfix". Simple text is capped at a reasonable width
|
||||
to enhance legibility. Necessitatibus dolor corrupti assumenda placeat quia occati
|
||||
@@ -262,6 +263,7 @@ showcases:
|
||||
collection:
|
||||
type: collection
|
||||
group: Collections
|
||||
default_state: expanded
|
||||
fields:
|
||||
set:
|
||||
type: set
|
||||
@@ -270,6 +272,7 @@ showcases:
|
||||
type: text
|
||||
textarea:
|
||||
type: textarea
|
||||
icon: fa-anchor
|
||||
relations:
|
||||
entries:
|
||||
multiple: false
|
||||
|
||||
Generated
+45
-33
@@ -32,13 +32,13 @@
|
||||
}
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.5.tgz",
|
||||
"integrity": "sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q==",
|
||||
"version": "7.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz",
|
||||
"integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.11.5",
|
||||
"@babel/generator": "^7.11.6",
|
||||
"@babel/helper-module-transforms": "^7.11.0",
|
||||
"@babel/helpers": "^7.10.4",
|
||||
"@babel/parser": "^7.11.5",
|
||||
@@ -52,7 +52,7 @@
|
||||
"lodash": "^4.17.19",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.4.1",
|
||||
"source-map": "^0.6.1"
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
@@ -65,14 +65,14 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz",
|
||||
"integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==",
|
||||
"version": "7.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz",
|
||||
"integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.11.5",
|
||||
"jsesc": "^2.5.1",
|
||||
"source-map": "^0.6.1"
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
@@ -174,6 +174,12 @@
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1097,14 +1103,14 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz",
|
||||
"integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==",
|
||||
"version": "7.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz",
|
||||
"integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.11.5",
|
||||
"jsesc": "^2.5.1",
|
||||
"source-map": "^0.6.1"
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
@@ -1191,6 +1197,12 @@
|
||||
"lodash": "^4.17.19",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6257,12 +6269,12 @@
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz",
|
||||
"integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==",
|
||||
"version": "4.14.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.1.tgz",
|
||||
"integrity": "sha512-zyBTIHydW37pnb63c7fHFXUG6EcqWOqoMdDx6cdyaDFriZ20EoVxcE95S54N+heRqY8m8IUgB5zYta/gCwSaaA==",
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001111",
|
||||
"electron-to-chromium": "^1.3.523",
|
||||
"caniuse-lite": "^1.0.30001124",
|
||||
"electron-to-chromium": "^1.3.562",
|
||||
"escalade": "^3.0.2",
|
||||
"node-releases": "^1.1.60"
|
||||
}
|
||||
@@ -6470,9 +6482,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001122",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001122.tgz",
|
||||
"integrity": "sha512-pxjw28CThdrqfz06nJkpAc5SXM404TXB/h5f4UJX+rrXJKE/1bu/KAILc2AY+O6cQIFtRjV9qOR2vaEp9LDGUA=="
|
||||
"version": "1.0.30001124",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz",
|
||||
"integrity": "sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA=="
|
||||
},
|
||||
"capture-exit": {
|
||||
"version": "2.0.0",
|
||||
@@ -8249,9 +8261,9 @@
|
||||
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA=="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.533",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.533.tgz",
|
||||
"integrity": "sha512-YqAL+NXOzjBnpY+dcOKDlZybJDCOzgsq4koW3fvyty/ldTmsb4QazZpOWmVvZ2m0t5jbBf7L0lIGU3BUipwG+A=="
|
||||
"version": "1.3.564",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.564.tgz",
|
||||
"integrity": "sha512-fNaYN3EtKQWLQsrKXui8mzcryJXuA0LbCLoizeX6oayG2emBaS5MauKjCPAvc29NEY4FpLHIUWiP+Y0Bfrs5dg=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.3",
|
||||
@@ -11219,7 +11231,7 @@
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
|
||||
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
|
||||
},
|
||||
"is-path-cwd": {
|
||||
@@ -13371,9 +13383,9 @@
|
||||
}
|
||||
},
|
||||
"locutus": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.11.tgz",
|
||||
"integrity": "sha512-C0q1L38lK5q1t+wE0KY21/9szrBHxye6o2z5EJzU+5B79tubNOC+nLAEzTTn1vPUGoUuehKh8kYKqiVUTWRyaQ==",
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.12.tgz",
|
||||
"integrity": "sha512-wnzhY9xOdDb2djr17kQhTh9oZgEfp78zI27KRRiiV1GnPXWA2xfVODbpH3QgpIuUMLupM02+6X/rJXvktTpnoA==",
|
||||
"requires": {
|
||||
"es6-promise": "^4.2.5"
|
||||
}
|
||||
@@ -13662,7 +13674,7 @@
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -14158,7 +14170,7 @@
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -16956,7 +16968,7 @@
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
|
||||
"requires": {
|
||||
"ret": "~0.1.10"
|
||||
@@ -18034,7 +18046,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
@@ -18058,7 +18070,7 @@
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
|
||||
},
|
||||
"strip-final-newline": {
|
||||
|
||||
+4
-4
@@ -32,14 +32,14 @@
|
||||
"baguettebox.js": "^1.11.1",
|
||||
"bootbox": "^5.4.0",
|
||||
"bootstrap": "^4.5.2",
|
||||
"browserslist": "^4.14.0",
|
||||
"caniuse-lite": "^1.0.30001122",
|
||||
"browserslist": "^4.14.1",
|
||||
"caniuse-lite": "^1.0.30001124",
|
||||
"codemirror": "^5.57.0",
|
||||
"dropzone": "^5.7.2",
|
||||
"flagpack": "^1.0.5",
|
||||
"hotkeys-js": "^3.8.1",
|
||||
"jquery": "^3.5.1",
|
||||
"locutus": "^2.0.11",
|
||||
"locutus": "^2.0.12",
|
||||
"luxon": "^1.25.0",
|
||||
"no-scroll": "^2.1.1",
|
||||
"node-vibrant": "^3.1.5",
|
||||
@@ -61,7 +61,7 @@
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.11.5",
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/plugin-transform-regenerator": "^7.10.4",
|
||||
"@babel/plugin-transform-runtime": "^7.11.5",
|
||||
"@babel/polyfill": "^7.11.5",
|
||||
|
||||
@@ -51,6 +51,7 @@ class FieldType extends Collection
|
||||
'default_locale' => 'en',
|
||||
// 10 rows by default
|
||||
'height' => '10',
|
||||
'icon' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,35 @@ class ContentFixtures extends BaseFixture implements DependentFixtureInterface,
|
||||
}
|
||||
|
||||
private function getValuesforFieldType(string $name, DeepCollection $field, bool $singleton): array
|
||||
{
|
||||
$data = isset($field['fixture_format']) ? $this->getFixtureFormatValues($field['fixture_format']) : $this->getFieldTypeValue($field, $singleton);
|
||||
|
||||
if ($name === 'title' || $name === 'heading') {
|
||||
$this->lastTitle = $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getFixtureFormatValues(string $format): array
|
||||
{
|
||||
return [preg_replace_callback(
|
||||
'/{([\w]+)}/i',
|
||||
function ($match) {
|
||||
$match = $match[1];
|
||||
|
||||
try {
|
||||
return $this->faker->{$match};
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
return '(unknown)';
|
||||
},
|
||||
$format
|
||||
)];
|
||||
}
|
||||
|
||||
private function getFieldTypeValue(DeepCollection $field, bool $singleton)
|
||||
{
|
||||
$nb = $singleton ? 8 : 4;
|
||||
|
||||
@@ -317,10 +346,6 @@ class ContentFixtures extends BaseFixture implements DependentFixtureInterface,
|
||||
$data = [$this->faker->sentence(6, true)];
|
||||
}
|
||||
|
||||
if ($name === 'title' || $name === 'heading') {
|
||||
$this->lastTitle = $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class HtmlExtension extends AbstractExtension
|
||||
return Html::makeAbsoluteLink($link);
|
||||
}
|
||||
|
||||
public function placeholders(string $string, array $replacements = []): string
|
||||
public function placeholders(?string $string = null, array $replacements = []): string
|
||||
{
|
||||
$baseReplacements = [
|
||||
'year' => date('Y'),
|
||||
@@ -115,6 +115,6 @@ class HtmlExtension extends AbstractExtension
|
||||
|
||||
$replacements = array_merge($baseReplacements, $replacements);
|
||||
|
||||
return Str::placeholders($string, $replacements, true);
|
||||
return Str::placeholders((string) $string, $replacements, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +175,15 @@ class ContentHelper
|
||||
return $field;
|
||||
}
|
||||
|
||||
if ($record->hasTaxonomyDefined($match[1])) {
|
||||
$result = [];
|
||||
foreach ($record->getTaxonomies($match[1]) as $item) {
|
||||
$result[] = $item->getName();
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
}
|
||||
|
||||
// We must ensure this method is not called recursively. For example
|
||||
// `title_format: {title}` would otherwise result in an endless loop
|
||||
// @see https://github.com/bolt/core/issues/1825
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
{# Setting the labels and their localisations that are used in the sidebar-menu. #}
|
||||
{% set labels = {
|
||||
'about.bolt_documentation': 'about.bolt_documentation'|trans,
|
||||
'action.view_site': 'action.view_site'|trans,
|
||||
'action.create_new': 'action.create_new'|trans,
|
||||
'action.view_site': config.get('general/sitename'),
|
||||
'general.greeting': 'general.greeting'|trans({'%name%': user_display_name}),
|
||||
'action.logout': 'action.logout'|trans,
|
||||
'action.edit_profile': 'action.edit_profile'|trans,
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
{% endapply %}{% endmacro %}
|
||||
|
||||
{% macro generate_collection_fields(collectionField, fields, compileTemplates) %}{% apply spaceless %}
|
||||
{% macro generate_collection_fields(collectionField, fields, record, compileTemplates) %}{% apply spaceless %}
|
||||
{% set fieldsHtml = [] %}
|
||||
{% for item_field in fields %}
|
||||
{% set collectionItemName = 'collections[' ~ collectionField.name ~ '][' ~ item_field.definition.name ~ ']' %}
|
||||
@@ -60,6 +60,7 @@
|
||||
'collection_name': collectionField.name,
|
||||
'collection_label': collectionField.definition.label,
|
||||
'hash': hash,
|
||||
'record': record
|
||||
} %}
|
||||
|
||||
{% if item_field.type != 'set' %}
|
||||
@@ -72,11 +73,22 @@
|
||||
'@bolt/_partials/fields/generic.html.twig'
|
||||
] %}
|
||||
|
||||
{% include includeLookup with context only %}
|
||||
<div>
|
||||
{% include includeLookup with context only %}
|
||||
<input type="hidden" name="collections[{{ collectionField.name }}][order][]" value="{{ hash }}" />
|
||||
</div>
|
||||
{% endset %}
|
||||
|
||||
{# Set the buttons #}
|
||||
{% set buttons %}{% include '@bolt/_partials/fields/_collection_buttons.html.twig' with { in_collection: true, 'hash': hash } %}{% endset %}
|
||||
|
||||
{# Set the icon #}
|
||||
{% set icon = item_field.definition.icon %}
|
||||
{% if icon is empty%}{% set icon = 'fa-plus' %}{% endif %}
|
||||
|
||||
{# set the label manually as set in _base.html.twig, to pass to Collection.vue for templates #}
|
||||
{% set label = item_field.definition.label|default(item_field.name|default('unnamed')|ucwords) %}
|
||||
{% set fieldsHtml = fieldsHtml|merge([{'html': new_field, 'hash': hash, 'label': label}]) %}
|
||||
{% set fieldsHtml = fieldsHtml|merge([{'content': new_field, 'hash': hash, 'label': label, 'buttons': buttons, 'icon': icon}]) %}
|
||||
{% endfor %}
|
||||
{{ fieldsHtml|json_encode }}
|
||||
{% endapply %}{% endmacro %}
|
||||
|
||||
@@ -128,7 +128,6 @@
|
||||
|
||||
{% block label %}
|
||||
{% include '@bolt/_partials/fields/_label.html.twig' %}
|
||||
{% include '@bolt/_partials/fields/_collection_buttons.html.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
{% if variant == 'inline' %}</div><div class="col-9">{% endif %}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{% if in_collection is defined %}
|
||||
<div class="float-right" role="group" aria-label="Collection buttons" style="margin-top: -0.25rem">
|
||||
<input type="hidden" name="collections[{{ collection_name }}][order][]" value="{{ hash }}" />
|
||||
|
||||
<div class="float-right btn-group" role="group" aria-label="Collection buttons">
|
||||
<button class='action-move-up-collection-item btn btn-secondary btn-sm' {% if is_first is defined and is_first %} disabled {% endif %}>
|
||||
<i class="fas fa-fw fa-chevron-up"></i>
|
||||
{{ 'collection.move_item_up'|trans }}
|
||||
|
||||
@@ -4,16 +4,20 @@
|
||||
{% block field %}
|
||||
{% set labels = {
|
||||
'add_collection_item': 'collection.add_item'|trans({'%name%': field.definition.label}),
|
||||
'expand_all': 'collection.expand_all'|trans,
|
||||
'collapse_all': 'collection.collapse_all'|trans,
|
||||
'select_tooltip': 'collection.select_tooltip'|trans,
|
||||
'field_label': label,
|
||||
} %}
|
||||
{% set limit = field.definition.get('limit')|default(200) %}
|
||||
|
||||
{# get the html for all collection field already in the database #}
|
||||
{% set existing_fields %}{{ macro.generate_collection_fields(field, field.value, false) }}{% endset %}
|
||||
{% set existing_fields %}{{ macro.generate_collection_fields(field, field.value, record, false) }}{% endset %}
|
||||
|
||||
{# get the html template for the collection fields defined in the field definition #}
|
||||
{% set templated_fields = "" %}
|
||||
{% if field.templates is defined %}
|
||||
{% set templated_fields %}{{ macro.generate_collection_fields(field, field.templates, true) }}{% endset %}
|
||||
{% set templated_fields %}{{ macro.generate_collection_fields(field, field.templates, record, true) }}{% endset %}
|
||||
{% endif %}
|
||||
|
||||
<editor-collection
|
||||
@@ -21,6 +25,7 @@
|
||||
:templates='{{ templated_fields }}'
|
||||
:labels='{{ labels | json_encode }}'
|
||||
:limit='{{ limit | json_encode }}'
|
||||
:state="{{ field.definition.get('default_state')|default('collapsed')|json_encode }}"
|
||||
></editor-collection>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -217,28 +217,22 @@ Feature: Edit record
|
||||
And I should see "Collection:" in the "label[for='field-collection']" element
|
||||
|
||||
#templates dropdown
|
||||
When I scroll "#multiselect-undefined > div > div.multiselect__select" into view
|
||||
And I click "#multiselect-undefined > div > div.multiselect__select"
|
||||
|
||||
Then I should see "Set" in the "#multiselect-undefined li:nth-child(1) > span" element
|
||||
And the "#multiselect-undefined li:nth-child(2) > span" element should contain "Textarea"
|
||||
|
||||
When I click "#multiselect-undefined > div > div.multiselect__select"
|
||||
And I click "#multiselect-undefined > div > div.multiselect__content-wrapper > ul > li:nth-child(2) > span"
|
||||
And I press "Add item"
|
||||
When I scroll "Add item to Collection" into view
|
||||
And I click "Add item to Collection"
|
||||
# Click add set
|
||||
And I click "#field-collection-collection > div > div.dropdown.show > div > a:nth-child(2)"
|
||||
|
||||
Then I should see an ".collection-item" element
|
||||
And I should see an ".trumbowyg-editor" element
|
||||
And I should see "Textarea:" in the "#collections label[for='field-collection-textarea-2']" element
|
||||
# And I should see "Textarea" in the "#collections label[for='field-collection-textarea-2']" element
|
||||
|
||||
And the 1st ".action-move-up-collection-item" button should be disabled
|
||||
And the 3rd ".action-move-down-collection-item" button should be disabled
|
||||
|
||||
When I scroll "Add item to Collection" into view
|
||||
And I click "#multiselect-undefined > div > div.multiselect__select"
|
||||
And I scroll "#multiselect-undefined > div > div.multiselect__content-wrapper > ul > li:nth-child(1)" into view
|
||||
And I click "#multiselect-undefined > div > div.multiselect__content-wrapper > ul > li:nth-child(1)"
|
||||
And I press "Add item"
|
||||
And I click "Add item to Collection"
|
||||
# Click add textarea
|
||||
And I click "#field-collection-collection > div > div.dropdown.show > div > a:nth-child(1)"
|
||||
|
||||
Then I should see 4 ".collection-item" elements
|
||||
|
||||
@@ -255,8 +249,17 @@ Feature: Edit record
|
||||
And I press "Save changes"
|
||||
Then I should be on "/bolt/edit/43#collections"
|
||||
|
||||
And the field ".collection-item:nth-child(3) input[type='text']" should contain "Hey, Bolt"
|
||||
And the field ".collection-item:nth-child(4) textarea" should contain "Bye, Bolt"
|
||||
And the field ".collection-item:nth-child(4) input[type='text']" should contain "Hey, Bolt"
|
||||
And the field ".collection-item:nth-child(5) textarea" should contain "Bye, Bolt"
|
||||
|
||||
And I should see "Hey, Bolt" in the ".collection-item:nth-child(4) .collection-item-title" element
|
||||
And I should see "Bye, Bolt" in the ".collection-item:nth-child(5) .collection-item-title" element
|
||||
|
||||
When I fill the 2nd "#collections textarea" element with ""
|
||||
And I fill the 2nd ".collection-item input[type='text']" element with ""
|
||||
|
||||
And I should see "Set" in the ".collection-item:nth-child(4) .collection-item-title" element
|
||||
And I should see "Textarea" in the ".collection-item:nth-child(5) .collection-item-title" element
|
||||
|
||||
When I scroll the 3rd "Remove item" into view
|
||||
And I press the 3rd "Remove item" button
|
||||
|
||||
@@ -17,7 +17,7 @@ class ContentTypesParserTest extends ParserTestBase
|
||||
|
||||
public const AMOUNT_OF_ATTRIBUTES_IN_CONTENT_TYPE = 25;
|
||||
|
||||
public const AMOUNT_OF_ATTRIBUTES_IN_FIELD = 25;
|
||||
public const AMOUNT_OF_ATTRIBUTES_IN_FIELD = 26;
|
||||
|
||||
public const ALLOWED_LOCALES = 'en|nl|es|fr|de|pl|it|hu|pt_BR|ja|nb|nn|nl_NL|nl_BE';
|
||||
|
||||
|
||||
@@ -2349,5 +2349,23 @@
|
||||
<target>Dependencies</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="H9knE.O" name="collection.expand_all">
|
||||
<segment>
|
||||
<source>collection.expand_all</source>
|
||||
<target>Expand all</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="JjvI6hp" name="collection.collapse_all">
|
||||
<segment>
|
||||
<source>collection.collapse_all</source>
|
||||
<target>Collapse all</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="wAltpsD" name="collection.select_tooltip">
|
||||
<segment>
|
||||
<source>collection.select_tooltip</source>
|
||||
<target>Select type of field to add</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
Reference in New Issue
Block a user