+ my $i = $self->param('_row_id');
+ die "invalid _row_id ",dump($i) unless $i =~ m/^\d+$/;
+ my $path = $self->param('path') || die "no path";
+ my $name = $self->param('name') || die "no name";
+ my $status = 200; # 200 = OK, 201 = Created
+
+ my $data = $self->_loaded('data');
+
+ if ( defined $loaded->{$path}->{data}->{items}->[$i] ) {
+ $content =~ s/^\s+//s;
+ $content =~ s/\s+$//s;
+ my $v;
+ if ( $content =~ /\xB6/ ) { # para
+ $v = [ split(/\s*\xB6\s*/, $content) ];
+ } else {
+ $v = [ $content ];
+ }
+
+ my $old = dump $loaded->{$path}->{data}->{items}->[$i]->{$name};
+ my $new = dump $v;
+ if ( $old ne $new
+ && ! ( $old eq 'undef' && length($content) == 0 ) # new value empty, previous undef
+ ) {
+ warn "# update $path $i $old -> $new\n";
+ $loaded->{$path}->{data}->{items}->[$i]->{$name} = $v;
+
+ if ( defined $loaded->{$path}->{sorted}->{$name} ) {
+ delete $loaded->{$path}->{sorted}->{$name};
+ warn "# invalidate $path sorted $name\n";
+ }
+
+ foreach ( grep { m/$name/ } keys %{ $loaded->{$path}->{filtered} } ) {
+ delete $loaded->{$path}->{filtered}->{$_};
+ warn "# invalidate $path filtered $_\n";
+ }
+
+ $status = 201; # created
+ $self->session('save_path' => $path);
+
+ } else {
+ warn "# unchanged $path $i $old\n";
+ $status = 304;
+ }
+ } else {
+ $content = "$path $i $name doesn't exist\n";
+ $status = 404;
+ }
+
+ warn "# edit $status $content";
+