Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List multi level #1181

Open
wants to merge 42 commits into
base: doryphore-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
325071d
Change List data structure
seballot Jul 2, 2024
c1058a4
disable eslint rule (we use new for Vue)
seballot Jul 2, 2024
6bacbc8
Refactor ListController to use VueJs
seballot Jul 2, 2024
4bde79e
list-form: ability to add children
seballot Jul 2, 2024
7640e1d
list-node-id: check of presence and uniquness
seballot Jul 2, 2024
0c7c4af
list: do not save vueRef in DB
seballot Jul 2, 2024
24d5145
list-form: specific label for child node
seballot Jul 2, 2024
6069864
Fix list import checkbox width
seballot Jul 2, 2024
287a790
feat(bazar-entry-form): Improve display for filter and check all
seballot Jul 2, 2024
7ed620d
Flatten the option tree so it work with all existing fields
seballot Jul 2, 2024
8a89e7c
Move fields/inputs js & css is dedicate folder
seballot Jul 2, 2024
5f07d35
Adds dedicate input (checkbox-tree) to render multi level list
seballot Jul 2, 2024
f5dffd5
linting
seballot Jul 2, 2024
a940706
wip
seballot Jul 2, 2024
e73b160
linting
seballot Jul 2, 2024
f804d49
facette: handle multi level list
seballot Jul 2, 2024
549e7e9
Only display option actually used by the entries list
seballot Jul 2, 2024
e39a169
Refactor formatFilters -> getFilters, calle the filter options "nodes"
seballot Jul 2, 2024
617e49a
Make all calculation recursive
seballot Jul 2, 2024
ec4b62f
Adds both parent and parents to each node
seballot Jul 2, 2024
6ad3e25
simplify tree logic by pre calculating all parents and descendants
seballot Jul 2, 2024
e92741a
hide icon in panel title beause it has a margin
seballot Jul 2, 2024
1625fe8
fix(bazar): field enum with empty children
mrflos Jul 2, 2024
3214b55
Refactor getFilters
seballot Jul 2, 2024
e121bb5
handle missing node
seballot Jul 2, 2024
146c84e
doc(README): fix typos
mrflos Jul 2, 2024
8287808
ListForm: abilty to drag and drop
seballot Jul 2, 2024
13d3e4a
checkbox tree: expandable children
seballot Jul 2, 2024
b69caec
chekcbox-tree adds "check all"
seballot Jul 2, 2024
f98e8fe
Rearrange bazar css and js file for more clarity
seballot Jul 2, 2024
aeb9a90
better throbber
seballot Jul 2, 2024
76d0c48
dynamic-filter: expandable checkboxes
seballot Jul 2, 2024
65b879c
Adds CollapseTransition and apply it to Panel
seballot Jul 2, 2024
1514099
bazar-indexfilters css refactor
seballot Jul 2, 2024
b75aa21
fix(bazar): php warning when empty children array
mrflos Jul 2, 2024
d28de48
lint
seballot Jul 2, 2024
06ee712
handle null data
seballot Jul 2, 2024
8d2804b
Change separator
seballot Jul 2, 2024
16d7362
Adjust default values to display select all button
seballot Jul 2, 2024
c4fa524
EnumField: propertyName to use the identifier provided in the form (n…
seballot Jul 2, 2024
996d3f4
hide filter without corresponding entries
seballot Jul 2, 2024
058830e
entry-show: better display for checkbox tree
seballot Jul 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ module.exports = {
wiki: 'writable',
Vue: 'readable',
_t: 'readable',
ace: 'writable'
ace: 'writable',
toastMessage: 'readable'
},
extends: [
'airbnb-base'
Expand All @@ -31,7 +32,8 @@ module.exports = {
'object-curly-newline': ['error', { multiline: true }],
'func-names': ['error', 'never'],
'space-before-function-paren': ['error', 'never'],
'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }]
'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
'no-new': 'off'
},
ignorePatterns: [
'vendor/',
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ We are using [weblate](https://hosted.weblate.org/yeswiki) to translate our soft

## Developers

We recommand an installation through docker.
We recommend an installation through docker.

### Linters & Formatters

Please install relevant extension and enable auto formating on your editor.
Please install relevant extension and enable auto formatting on your editor.

Alternatly you can run `make lint`
Alternatively you can run `make lint`

| Language | Linter/Formatter |
| --------------------------- | ------------------------------------------------------------ |
Expand All @@ -42,7 +42,7 @@ Alternatly you can run `make lint`
| Twig | no automatic linter. Couldn't find one which is good enough. |
| CSS, Yaml, JSON, Markdown.. | `prettier` |

If you use VS Codium, get yeswiki linting settings with `cp .vscode/settings.example.json .vscode/settings.json`
If you use VS Codium, get YesWiki linting settings with `cp .vscode/settings.example.json .vscode/settings.json`

## History

Expand Down Expand Up @@ -71,4 +71,4 @@ YesWiki grew out of a French language version of [WakkaWiki](https://en.wikipedi

### YesWiki authors

See <https://github.com/YesWiki/yeswiki/graphs/contributors>
See <https://github.com/YesWiki/yeswiki/graphs/contributors>
2 changes: 1 addition & 1 deletion handlers/EditIframeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function run()
}
}

$this->wiki->AddJavascriptFile('tools/bazar/libs/bazar.js');
$this->wiki->AddJavascriptFile('tools/bazar/presentation/javascripts/bazar.js');
$output .= '<body class="yeswiki-iframe-body">' . "\n"
. '<div class="container">' . "\n"
. '<div class="yeswiki-page-widget page-widget page">' . "\n";
Expand Down
2 changes: 1 addition & 1 deletion handlers/IframeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private function renderBazarEntry(): string
{
$output = '';
// si la page est une fiche bazar, alors on affiche la fiche plutot que de formater en wiki
$this->wiki->AddJavascriptFile('tools/bazar/libs/bazar.js');
$this->wiki->AddJavascriptFile('tools/bazar/presentation/javascripts/bazar.js');
$valjson = $this->wiki->page['body'];
$tab_valeurs = json_decode($valjson, true);
if (YW_CHARSET != 'UTF-8') {
Expand Down
26 changes: 26 additions & 0 deletions includes/migrations/20240502083251_RefactorListStruture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

use YesWiki\Bazar\Service\ListManager;
use YesWiki\Core\Service\PageManager;
use YesWiki\Core\Service\TripleStore;
use YesWiki\Core\YesWikiMigration;

// Convert old List { titre_liste: "My List", label: { id1: "first Key", id2: "second id" } }
// to { title: "My List", values: [{ id: "id1", label: "first id"}, { id: "id2", label: "second id"}]}
class RefactorListStruture extends YesWikiMigration
{
public function run()
{
$tripleStore = $this->wiki->services->get(TripleStore::class);
$pageManager = $this->wiki->services->get(PageManager::class);
$listManager = $this->wiki->services->get(ListManager::class);
$lists = $tripleStore->getMatching(null, TripleStore::TYPE_URI, ListManager::TRIPLES_LIST_ID, '', '');
foreach ($lists as $list) {
$tag = $list['resource'];
$page = $pageManager->getOne($tag);
$oldJson = json_decode($page['body'], true);
$newJson = $listManager->convertDataStructure($oldJson);
$pageManager->save($tag, json_encode($newJson));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use YesWiki\Bazar\Field\EnumField;
use YesWiki\Bazar\Service\FieldFactory;
use YesWiki\Bazar\Service\FormManager;
use YesWiki\Core\YesWikiMigration;

class RefactorEnumFieldPropertyName extends YesWikiMigration
{
public function run()
{
$formManager = $this->getService(FormManager::class);
$fieldFactory = $this->getService(FieldFactory::class);
$forms = $formManager->getAll();
foreach ($forms as $form) {
$newTemplate = [];
foreach ($form['template'] as $fieldArray) {
$field = $fieldFactory->create($fieldArray);
if ($field instanceof EnumField) {
$fieldArray[EnumField::FIELD_NAME] = $field->getType() . $field->getLinkedObjectName() . $field->getName();
}
$newTemplate[] = $fieldArray;
}
$form['bn_template'] = $formManager->encodeTemplate($newTemplate);
$formManager->update($form);
}
}
}
223 changes: 223 additions & 0 deletions javascripts/shared-components/CollapseTransition.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i definitely prefer jquery and vanilla css transitions 🧓

Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// This code come from https://github.com/BinarCode/vue2-transitions

const BaseTransitionMixin = {
inheritAttrs: false,
props: {
/**
* Transition duration. Number for specifying the same duration for enter/leave transitions
* Object style {enter: 300, leave: 300} for specifying explicit durations for enter/leave
*/
duration: {
type: [Number, Object],
default: 200
},
/**
* Transition delay. Number for specifying the same delay for enter/leave transitions
* Object style {enter: 300, leave: 300} for specifying explicit durations for enter/leave
*/
delay: {
type: [Number, Object],
default: 0
},
/**
* Whether the component should be a `transition-group` component.
*/
group: Boolean,
/**
* Transition tag, in case the component is a `transition-group`
*/
tag: {
type: String,
default: 'span'
},
/**
* Transform origin property https://tympanus.net/codrops/css_reference/transform-origin/.
* Can be specified with styles as well but it's shorter with this prop
*/
origin: {
type: String,
default: ''
},
/**
* Element styles that are applied during transition. These styles are applied on @beforeEnter and @beforeLeave hooks
*/
styles: {
type: Object,
default: () => ({
animationFillMode: 'both',
animationTimingFunction: 'ease-out'
})
}
},
computed: {
componentType() {
return this.group ? 'transition-group' : 'transition'
},
hooks() {
return {
...this.$listeners,
beforeEnter: this.beforeEnter,
afterEnter: (el) => {
this.cleanUpStyles(el)
this.$emit('after-enter', el)
},
beforeLeave: this.beforeLeave,
leave: this.leave,
afterLeave: (el) => {
this.cleanUpStyles(el)
this.$emit('after-leave', el)
}
}
}
},
methods: {
beforeEnter(el) {
const enterDuration = this.duration.enter ? this.duration.enter : this.duration
el.style.animationDuration = `${enterDuration}ms`

const enterDelay = this.delay.enter ? this.delay.enter : this.delay
el.style.animationDelay = `${enterDelay}ms`

this.setStyles(el)
this.$emit('before-enter', el)
},
cleanUpStyles(el) {
Object.keys(this.styles).forEach((key) => {
const styleValue = this.styles[key]
if (styleValue) {
el.style[key] = ''
}
})
el.style.animationDuration = ''
el.style.animationDelay = ''
},
beforeLeave(el) {
const leaveDuration = this.duration.leave ? this.duration.leave : this.duration
el.style.animationDuration = `${leaveDuration}ms`

const leaveDelay = this.delay.leave ? this.delay.leave : this.delay
el.style.animationDelay = `${leaveDelay}ms`

this.setStyles(el)
this.$emit('before-leave', el)
},
leave(el, done) {
this.setAbsolutePosition(el)
this.$emit('leave', el, done)
},
setStyles(el) {
this.setTransformOrigin(el)
Object.keys(this.styles).forEach((key) => {
const styleValue = this.styles[key]
if (styleValue) {
el.style[key] = styleValue
}
})
},
setAbsolutePosition(el) {
if (this.group) {
el.style.position = 'absolute'
}
return this
},
setTransformOrigin(el) {
if (this.origin) {
el.style.transformOrigin = this.origin
}
return this
}
}
}

export default {
name: 'collapse-transition',
mixins: [BaseTransitionMixin],
methods: {
transitionStyle(duration = 300) {
const durationInSeconds = duration / 1000
const style = `${durationInSeconds}s height ease-in-out, ${durationInSeconds}s padding-top ease-in-out, ${durationInSeconds}s padding-bottom ease-in-out`
return style
},
beforeEnter(el) {
const enterDuration = this.duration.enter ? this.duration.enter : this.duration
el.style.transition = this.transitionStyle(enterDuration)
if (!el.dataset) el.dataset = {}

el.dataset.oldPaddingTop = el.style.paddingTop
el.dataset.oldPaddingBottom = el.style.paddingBottom

el.style.height = '0'
el.style.paddingTop = 0
el.style.paddingBottom = 0
this.setStyles(el)
},

enter(el) {
el.dataset.oldOverflow = el.style.overflow
if (el.scrollHeight !== 0) {
el.style.height = `${el.scrollHeight}px`
el.style.paddingTop = el.dataset.oldPaddingTop
el.style.paddingBottom = el.dataset.oldPaddingBottom
} else {
el.style.height = ''
el.style.paddingTop = el.dataset.oldPaddingTop
el.style.paddingBottom = el.dataset.oldPaddingBottom
}

el.style.overflow = 'hidden'
},

afterEnter(el) {
// for safari: remove class then reset height is necessary
el.style.transition = ''
el.style.height = ''
el.style.overflow = el.dataset.oldOverflow
},

beforeLeave(el) {
if (!el.dataset) el.dataset = {}
el.dataset.oldPaddingTop = el.style.paddingTop
el.dataset.oldPaddingBottom = el.style.paddingBottom
el.dataset.oldOverflow = el.style.overflow

el.style.height = `${el.scrollHeight}px`
el.style.overflow = 'hidden'
this.setStyles(el)
},

leave(el) {
const leaveDuration = this.duration.leave ? this.duration.leave : this.duration
if (el.scrollHeight !== 0) {
// for safari: add class after set height, or it will jump to zero height suddenly, weired
el.style.transition = this.transitionStyle(leaveDuration)
el.style.height = 0
el.style.paddingTop = 0
el.style.paddingBottom = 0
}
// necessary for transition-group
this.setAbsolutePosition(el)
},

afterLeave(el) {
el.style.transition = ''
el.style.height = ''
el.style.overflow = el.dataset.oldOverflow
el.style.paddingTop = el.dataset.oldPaddingTop
el.style.paddingBottom = el.dataset.oldPaddingBottom
}
},
template: `
<component :is="componentType"
:tag="tag"
v-bind="$attrs"
v-on="$listeners"
@before-enter="beforeEnter"
@after-enter="afterEnter"
@enter="enter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
move-class="collapse-move">
<slot></slot>
</component>`
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import CollapseTransition from './CollapseTransition.js'

export default {
props: {
color: {
Expand All @@ -13,8 +15,11 @@ export default {
default: true
}
},
components: { CollapseTransition },
data() {
return { internalCollapsed: true // value to work internally, name should not conflict with prop
return {
// value to work internally, name should not conflict with prop
internalCollapsed: true
}
},
computed: {
Expand All @@ -30,7 +35,7 @@ export default {
if (!this.internalCollapsed) this.$emit('opened')
}
},
mounted() {
beforeMount() {
this.internalCollapsed = this.collapsed
},
template: `
Expand All @@ -40,10 +45,11 @@ export default {
@click="headerClicked()">
<slot name="header"></slot>
</button>
<div class="panel-body" v-show="!internalCollapsed" style="padding: 0">
<slot name="body"></slot>
</div>
</div>
<collapse-transition>
<div class="panel-body" v-show="!internalCollapsed" style="padding: 0">
<slot name="body"></slot>
</div>
</collapse-transition>
</div>
`
}
Loading