remove fieldsets and add tabs to model instead

This commit is contained in:
Mads Rasmussen
2021-03-05 16:03:39 +01:00
parent 751b5ab859
commit b403a2bee4
5 changed files with 109 additions and 208 deletions

View File

@@ -14,29 +14,12 @@
scope.dataTypeHasChanged = false;
scope.sortingMode = false;
scope.toolbar = [];
scope.sortableOptionsGroup = {};
scope.sortableOptionsFieldset = {};
scope.sortableOptionsProperty = {};
scope.sortableOptionsTabs = {};
scope.sortingButtonKey = "general_reorder";
scope.compositionsButtonState = "init";
function activate() {
setSortingOptions();
// set placeholder property on each group
if (scope.model.groups.length !== 0) {
angular.forEach(scope.model.groups, function (group) {
addInitProperty(group);
});
}
// add init tab
addInitGroup(scope.model.groups);
activateFirstGroup(scope.model.groups);
// localize texts
localizationService.localize("validation_validation").then(function (value) {
validationTranslated = value;
@@ -50,63 +33,56 @@
function setSortingOptions() {
const defaultOptions = {
axis: 'y',
axis: '',
tolerance: "pointer",
opacity: 0.7,
scroll: true,
cursor: "move",
zIndex: 6000,
forcePlaceholderSize: true,
dropOnEmpty: true
dropOnEmpty: true,
helper: "clone",
appendTo: "body"
};
scope.sortableOptionsGroup = {
...defaultOptions,
connectWith: ".umb-group-builder__groups",
placeholder: "umb-group-builder__group-sortable-placeholder",
handle: ".umb-group-builder__group-handle",
items: ".umb-group-builder__group-sortable",
stop: function (e, ui) {
updateTabsSortOrder();
}
};
scope.sortableOptionsFieldset = {
...defaultOptions,
placeholder: "umb-group-builder__group-sortable-placeholder",
handle: ".umb-group-builder__group-handle",
items: ".umb-group-builder__fieldset-sortable",
stop: function (e, ui) {
updateFieldsetsSortOrder();
stop: function (event, ui) {
// make sure reference to tab is correct
const groupId = ui.item[0].dataset.groupId ? parseInt(ui.item[0].dataset.groupId) : null;
const group = groupId ? scope.model.groups.find(group => group.id === parseInt(groupId)) : null;
group.tabId = scope.openTabId;
// TODO: Manually update the model based on the sorting of group in tabs
// updateGroupsSortOrder();
}
};
scope.sortableOptionsProperty = {
...defaultOptions,
axis: '',
connectWith: ".umb-group-builder__properties",
placeholder: "umb-group-builder__property_sortable-placeholder",
handle: ".umb-group-builder__property-handle",
items: ".umb-group-builder__property-sortable",
helper: "clone",
appendTo: "body",
stop: function (e, ui) {
updatePropertiesSortOrder();
// updatePropertiesSortOrder();
}
};
scope.droppableOptionsTab = {
accept: '.umb-group-builder__property-sortable',
accept: '.umb-group-builder__property-sortable, .umb-group-builder__group-sortable',
tolerance : 'pointer',
over: function (evt, ui) {
const tabDropId = evt.target.dataset.tabDropId ? parseInt(evt.target.dataset.tabDropId) : null;
const tabIndex = scope.model.groups.findIndex(group => group.id === tabDropId);
scope.openTabIndex = tabIndex !== -1 ? tabIndex : scope.openTabIndex;
scope.openTabId = evt.target.dataset.tabId ? parseInt(evt.target.dataset.tabId) : null;
scope.$evalAsync();
}
};
}
function updateTabsSortOrder() {
function updateGroupsSortOrder() {
var first = true;
var prevSortOrder = 0;
@@ -255,10 +231,8 @@
}
} else {
scope.sortingMode = true;
scope.sortingButtonKey = "general_reorderDone";
}
};
@@ -404,38 +378,40 @@
};
/* ---------- TABS ---------- */
scope.model.hasTabs = true;
scope.openTabIndex = 0;
scope.changeTab = function (index) {
scope.openTabIndex = index;
scope.changeTab = function ({ id }) {
scope.openTabId = id;
};
scope.addTab = function (tab) {
scope.addGroup(tab);
scope.openTabIndex = scope.model.groups.length - 2;
};
scope.addTab = function () {
scope.model.tabs = scope.model.tabs || [];
scope.addFieldset = function (group) {
if (!group) {
return;
}
const newTabIndex = scope.model.tabs.length;
const lastTab = scope.model.tabs[newTabIndex - 1];
const sortOrder = lastTab && lastTab.sortOrder !== undefined ? lastTab.sortOrder + 1 : 0;
if (!group.fieldsets) {
group.fieldsets = [];
}
const fieldset = {
groupId: group.id,
id: group.fieldsets.length + 1, // temp id
const tab = {
id: newTabIndex + 1, // temp id
name: "",
properties: []
sortOrder
};
group.fieldsets = [...group.fieldsets, fieldset];
if (newTabIndex === 0) {
scope.model.groups.forEach(group => group.tabId = tab.id);
}
updateFieldsetsSortOrder();
scope.model.tabs = [...scope.model.tabs, tab];
scope.openTabId = tab.id;
};
scope.removeTab = function (index) {
scope.model.tabs.splice(index, 1);
};
scope.canRemoveTab = function (tab) {
return tab.inherited !== true;
};
scope.addNewProperty = function (group) {
@@ -477,35 +453,30 @@
editorService.open(propertySettings);
};
/* ---------- FIELDSETS ---------- */
scope.removeFieldset = function (items, { id }) {
const index = items.map(item => item.id).findIndex(itemId => itemId === id);
items.splice(index, 1);
notifyChanged();
};
/* ---------- GROUPS ---------- */
scope.addGroup = function (group) {
scope.addGroup = function (tabId) {
scope.model.groups = scope.model.groups || [];
// set group sort order
var index = scope.model.groups.indexOf(group);
var prevGroup = scope.model.groups[index - 1];
if (index > 0) {
// set index to 1 higher than the previous groups sort order
group.sortOrder = prevGroup.sortOrder + 1;
} else {
// first group - sort order will be 0
group.sortOrder = 0;
}
// activate group
scope.activateGroup(group);
/*
const groupsInTab = tabId ? scope.model.groups.filter(group => group.tabId === tabId) : scope.model.groups;
const prevGroup = groupsInTab[groupsInTab.length - 1];
const sortOrder = prevGroup && prevGroup.sortOrder !== undefined ? prevGroup.sortOrder + 1 : 0;
*/
// push new init tab to the scope
addInitGroup(scope.model.groups);
const group = {
properties: [],
parentTabContentTypes: [],
parentTabContentTypeNames: [],
name: "",
tabId: tabId || undefined,
sortOrder
};
scope.model.groups = [...scope.model.groups, group];
};
scope.activateGroup = function (selectedGroup) {
@@ -535,45 +506,10 @@
if (group.sortOrder !== undefined) {
group.showSortOrderMissing = false;
}
scope.model.groups = $filter('orderBy')(scope.model.groups, 'sortOrder');
};
function addInitGroup(groups) {
var addGroup = true;
angular.forEach(groups, function (group) {
if (group.tabState === "init") {
addGroup = false;
}
});
if (addGroup) {
let group = {
properties: [],
parentTabContentTypes: [],
parentTabContentTypeNames: [],
name: "",
tabState: "init",
id: groups.length + 1
};
group = addInitProperty(group);
groups.push(group);
}
return groups;
}
function activateFirstGroup(groups) {
if (groups && groups.length > 0) {
var firstGroup = groups[0];
if (!firstGroup.tabState || firstGroup.tabState === "inActive") {
firstGroup.tabState = "active";
}
}
}
/* ---------- PROPERTIES ---------- */
scope.addPropertyToActiveGroup = function () {

View File

@@ -282,12 +282,15 @@ input.umb-group-builder__group-title-input:disabled:hover {
}
}
.umb-group-builder__group-content {
padding: 10px 20px 20px 20px;
}
/* ---------- PROPERTIES ---------- */
.umb-group-builder__properties {
list-style: none;
margin: 0;
padding: 15px;
padding-right: 5px;
min-height: 35px; // the height of a sortable property
}
@@ -301,14 +304,6 @@ input.umb-group-builder__group-title-input:disabled:hover {
padding: 10px 0;
}
.umb-group-builder__property:first-of-type {
padding-top: 0;
}
.umb-group-builder__property:last-of-type {
margin-bottom: 15px;
}
.umb-group-builder__property.-inherited {
animation: fadeIn 0.5s;
}

View File

@@ -1,10 +1,10 @@
<div class="umb-group-builder__group" ng-class="{'-inherited': vm.group.inherited, 'umb-group-builder__group-handle -sortable': vm.sorting}">
<div class="umb-group-builder__group" ng-class="{'-inherited': vm.group.inherited, 'umb-group-builder__group-handle -sortable': vm.sorting && !vm.group.inherited}">
<div class="umb-group-builder__group-title-wrapper" ng-if="vm.allowName">
<ng-form name="groupNameForm" data-element="group-name">
<div class="umb-group-builder__group-title control-group -no-margin" ng-class="{'-inherited': vm.group.inherited}">
<i class="umb-group-builder__group-title-icon icon-navigation" ng-if="vm.sorting"></i>
<i class="umb-group-builder__group-title-icon icon-navigation" ng-if="vm.sorting && !vm.group.inherited"></i>
<input data-element="group-name-field"
class="umb-group-builder__group-title-input"
type="text"
@@ -61,6 +61,8 @@
</div>
</div>
<ng-transclude></ng-transclude>
<div class="umb-group-builder__group-content">
<ng-transclude></ng-transclude>
</div>
</div>

View File

@@ -3,12 +3,6 @@
<umb-editor-sub-header>
<umb-editor-sub-header-content-right>
<div class="flex items-center">
<div>Use Tabs (debug and demo)</div>
<input type="checkbox" ng-model="model.hasTabs" />
</div>
<umb-button
style="margin-right: 5px;"
alias="compositions"
@@ -46,9 +40,9 @@
<!-- WITH TABS --->
<div ng-if="model.hasTabs">
<ul class="umb-group-builder__tabs" ui-sortable="sortableOptionsTabs" ng-model="model.groups">
<li ng-repeat="tab in model.groups" ng-class="{'umb-group-builder__tab-sortable': sortingMode}" umb-droppable="droppableOptionsTab" data-tab-drop-id="{{tab.id}}">
<div ng-if="tab.tabState !== 'init'" ng-click="changeTab($index)" class="umb-group-builder__tab" ng-class="{'is-active': $index === openTabIndex, 'is-inherited': tab.inherited, 'umb-group-builder__tab-handle -sortable': sortingMode && !tab.inherited}">
<ul class="umb-group-builder__tabs" ui-sortable="sortableOptionsTabs" ng-model="model.tabs">
<li ng-repeat="tab in model.tabs" ng-class="{'umb-group-builder__tab-sortable': sortingMode}" umb-droppable="droppableOptionsTab" data-tab-id="{{tab.id}}">
<div ng-click="changeTab(tab)" class="umb-group-builder__tab" ng-class="{'is-active': tab.id === openTabId, 'is-inherited': tab.inherited, 'umb-group-builder__tab-handle -sortable': sortingMode && !tab.inherited}">
<div>
<div class="umb-group-builder__tab-inherited-label" ng-if="tab.inherited">
<localize key="contentTypeEditor_inheritedFrom"></localize>: {{ tab.inheritedFromName }}
@@ -59,28 +53,28 @@
</div>
<div class="umb-group-builder__tab-title-wrapper">
<i class="umb-group-builder__tab-title-icon icon-navigation" ng-if="sortingMode && !tab.inherited"></i>
<ng-form name="groupNameForm" data-element="group-name">
<ng-form name="tabNameForm" data-element="group-name">
<div class="umb-group-builder__tab-name" ng-if="tab.inherited || sortingMode">{{ tab.name }}</div>
<!-- ng-focus="activateGroup(tab)" -->
<input
ng-if="!tab.inherited && !sortingMode"
class="umb-group-builder__group-title-input"
data-element="group-name-field"
data-element="tab-name-field"
type="text"
localize="placeholder"
placeholder="@placeholders_entername"
name="groupName"
name="tabName"
ng-model="tab.name"
ng-class="{'-placeholder': tab.name == ''}"
ng-disabled="$index !== openTabIndex"
ng-disabled="tab.id !== openTabId"
umb-auto-focus
umb-auto-resize
ng-focus="activateGroup(tab)"
required
val-server-field="{{'Groups[' + $index + '].Name'}}"
val-server-field="{{'Tabs[' + $index + '].Name'}}"
data-lpignore="true" />
<div class="umb-group-builder__tab-val-message" ng-messages="groupNameForm.groupName.$error" show-validation-on-submit>
<div class="umb-validation-label -arrow-bottom" ng-message="valServerField">{{groupNameForm.groupName.errorMsg}}</div>
<div class="umb-group-builder__tab-val-message" ng-messages="tabNameForm.tabName.$error" show-validation-on-submit>
<div class="umb-validation-label -arrow-bottom" ng-message="valServerField">{{tabNameForm.tabName.errorMsg}}</div>
<div class="umb-validation-label -arrow-bottom" ng-message="required"><localize key="required"></localize></div>
</div>
</ng-form>
@@ -98,88 +92,63 @@
</ng-form>
</div>
</div>
<div class="umb-group-builder__tab-remove" ng-if="!sortingMode && canRemoveGroup(tab)">
<div class="umb-group-builder__tab-remove" ng-if="!sortingMode && canRemoveTab(tab)">
<button type="button" class="btn-reset" ng-click="togglePrompt(tab)">
<i class="icon-trash"></i>
</button>
<umb-confirm-action
ng-if="tab.deletePrompt"
direction="left"
on-confirm="removeGroup($index)"
on-confirm="removeTab($index)"
on-cancel="hidePrompt(tab)">
</umb-confirm-action>
</div>
</div>
<button ng-if="tab.tabState ==='init' && !sortingMode" type="button" hotkey="alt+shift+t" ng-click="addTab(tab)" data-element="group-add" class="btn-reset umb-group-builder__tab umb-group-builder__tab--placeholder">
</li>
<li>
<button ng-if="!sortingMode" type="button" hotkey="alt+shift+t" ng-click="addTab(tab)" data-element="group-add" class="btn-reset umb-group-builder__tab umb-group-builder__tab--placeholder">
Add tab
</button>
</li>
</ul>
<umb-content-type-groups>
<div ng-repeat="group in model.groups" ng-hide="$index !== openTabIndex">
<umb-content-type-group>
<div class="umb-group-builder__groups" ui-sortable="sortableOptionsGroup" ng-model="model.groups">
<div ng-repeat="(groupIndex, group) in model.groups" ng-show="group.tabId === openTabId" ng-class="{'umb-group-builder__group-sortable': sortingMode && !group.inherited}" data-group-id="{{group.id}}">
<umb-content-type-group
ng-if="group.tabState !== 'init'"
allow-name="true"
group="group"
allow-remove="!sortingMode"
on-remove="removeGroup(groupIndex)"
sorting="sortingMode"
name-val-server-field="{{'Groups[' + $index + '].Name'}}">
<ul class="umb-group-builder__properties" ui-sortable="sortableOptionsProperty" ng-model="group.properties">
<li ng-repeat="property in group.properties" data-element="property-{{property.alias}}" ng-class="{'umb-group-builder__property-sortable': sortingMode && !property.inherited}">
<li ng-repeat="(propertyIndex, property) in group.properties" data-element="property-{{property.alias}}" ng-class="{'umb-group-builder__property-sortable': sortingMode && !property.inherited}">
<umb-content-type-property
ng-if="property.propertyState !== 'init'"
property="property"
sortable="sortingMode"
on-edit="editPropertyTypeSettings(property)"
on-remove="deleteProperty(model.groups[openTabIndex].properties, property)"
alias-val-server-field="{{'Groups[' + openTabIndex + '].Properties[' + group.properties.indexOf(property) + '].Alias'}}"
label-val-server-field="{{'Groups[' + openTabIndex + '].Properties[' + group.properties.indexOf(property) + '].Label'}}">
on-remove="deleteProperty(group.properties, property)"
alias-val-server-field="{{'Groups[' + groupIndex + '].Properties[' + propertyIndex + '].Alias'}}"
label-val-server-field="{{'Groups[' + groupIndex + '].Properties[' + propertyIndex + '].Label'}}">
</umb-content-type-property>
<umb-content-type-property-placeholder
ng-if="property.propertyState === 'init' && !sortingMode"
on-click="addProperty(property, group)"
focus="property.focus">
</umb-content-type-property-placeholder>
</li>
</ul>
<umb-content-type-property-placeholder
ng-if="!sortingMode"
on-click="addNewProperty(group, group.id)">
</umb-content-type-property-placeholder>
</umb-content-type-group>
<div class="umb-group-builder__fieldsets" ui-sortable="sortableOptionsFieldset" ng-model="group.fieldsets">
<div ng-repeat="fieldset in group.fieldsets" ng-class="{'umb-group-builder__fieldset-sortable': sortingMode && !fieldset.inherited}">
<umb-content-type-group
allow-name="true"
group="fieldset"
allow-remove="!sortingMode"
on-remove="removeFieldset(group.fieldsets, fieldset)"
sorting="sortingMode && !fieldset.inherited"
name-val-server-field="{{'Fieldsets[' + model.fieldsets.indexOf(fieldset) + '].Name'}}">
<ul class="umb-group-builder__properties" ui-sortable="sortableOptionsProperty" ng-model="fieldset.properties">
<li ng-repeat="property in fieldset.properties" data-element="property-{{property.alias}}" ng-class="{'umb-group-builder__property-sortable': sortingMode && !property.inherited}">
<umb-content-type-property
property="property"
sortable="sortingMode"
on-edit="editPropertyTypeSettings(property)"
on-remove="deleteProperty(fieldset.properties, property)"
alias-val-server-field="{{'Groups[' + openTabIndex + '].Properties[' + model.groups[openTabIndex].properties.indexOf(property) + '].Alias'}}"
label-val-server-field="{{'Groups[' + openTabIndex + '].Properties[' + model.groups[openTabIndex].properties.indexOf(property) + '].Label'}}">
</umb-content-type-property>
</li>
<li>
<umb-content-type-property-placeholder
ng-if="!sortingMode"
on-click="addNewProperty(fieldset, fieldset.id)">
</umb-content-type-property-placeholder>
</li>
</ul>
</umb-content-type-group>
</div>
</div>
</div>
<umb-content-type-group-placeholder
ng-if="model.groups.length > 1 && !sortingMode"
on-click="addFieldset(model.groups[openTabIndex])">
<localize key="contentTypeEditor_addFieldset"></localize>
</umb-content-type-group-placeholder>
</umb-content-type-groups>
</div>
<umb-content-type-group-placeholder
ng-if="!sortingMode"
on-click="addGroup(openTabId)">
<localize key="contentTypeEditor_addGroup"></localize>
</umb-content-type-group-placeholder>
</div>
<!-- WITHOUT TABS -->

View File

@@ -19,7 +19,6 @@
ng-class="{'-unlocked': !locked}"
placeholder="{{placeholderText}}"
val-regex="{{regexValidation}}"
umb-auto-resize
required
val-server-field="{{serverValidationField}}"
title="{{ngModel}}"