• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

knowledgepixels / nanodash / 18596035671

17 Oct 2025 02:37PM UTC coverage: 13.583% (-0.9%) from 14.51%
18596035671

push

github

tkuhn
feat(Spaces): Use context param to direct user back to space page

452 of 4210 branches covered (10.74%)

Branch coverage included in aggregate %.

1171 of 7739 relevant lines covered (15.13%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
src/main/java/com/knowledgepixels/nanodash/component/ItemListPanel.java
1
package com.knowledgepixels.nanodash.component;
2

3
import java.io.Serializable;
4
import java.util.ArrayList;
5
import java.util.List;
6
import java.util.function.Function;
7
import java.util.function.Supplier;
8

9
import org.apache.wicket.Component;
10
import org.apache.wicket.behavior.AttributeAppender;
11
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
12
import org.apache.wicket.markup.html.basic.Label;
13
import org.apache.wicket.markup.html.link.AbstractLink;
14
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
15
import org.apache.wicket.markup.html.panel.Panel;
16
import org.apache.wicket.model.Model;
17
import org.apache.wicket.request.mapper.parameter.PageParameters;
18
import org.nanopub.extra.services.ApiResponse;
19
import org.nanopub.extra.services.QueryRef;
20

21
import com.knowledgepixels.nanodash.ApiCache;
22
import com.knowledgepixels.nanodash.Space;
23
import com.knowledgepixels.nanodash.page.NanodashPage;
24

25
public class ItemListPanel<T extends Serializable> extends Panel {
26

27
    private String description;
28
    private List<AbstractLink> buttons = new ArrayList<>();
×
29
    private List<AbstractLink> memberButtons = new ArrayList<>();
×
30
    private List<AbstractLink> adminButtons = new ArrayList<>();
×
31
    private Space space;
32
    private boolean finalized = false;
×
33
    private boolean lazyLoading = false;
×
34
    private ReadyFunction readyFunction;
35

36
    private ItemListPanel(String markupId, String title) {
37
        super(markupId);
×
38
        setOutputMarkupId(true);
×
39

40
        add(new Label("title", title));
×
41
    }
×
42
    
43
    public ItemListPanel(String markupId, String title, List<T> items, ComponentProvider<T> compProvider) {
44
        this(markupId, title);
×
45

46
        add(new ItemList<T>("itemlist", items, compProvider));
×
47
    }
×
48

49
    public ItemListPanel(String markupId, String title, QueryRef queryRef, ApiResultListProvider<T> resultListProvider, ComponentProvider<T> compProvider) {
50
        this(markupId, title);
×
51

52
        ApiResponse qResponse = ApiCache.retrieveResponse(queryRef);
×
53
        if (qResponse != null) {
×
54
            add(new ItemList<T>("itemlist", resultListProvider.apply(qResponse), compProvider));
×
55
        } else {
56
            lazyLoading = true;
×
57
            add(new ApiResultComponent("itemlist", queryRef) {
×
58

59
                @Override
60
                public Component getApiResultComponent(String markupId, ApiResponse response) {
61
                    return new ItemList<T>(markupId, resultListProvider.apply(response), compProvider);
×
62
                }
63
            });
64
        }
65
    }
×
66

67
    public ItemListPanel(String markupId, String title, ReadyFunction readyFunction, ResultFunction<List<T>> resultFunction, ComponentProvider<T> compProvider) {
68
        this(markupId, title);
×
69
        this.readyFunction = readyFunction;
×
70

71
        if (readyFunction.get()) {
×
72
            add(new ItemList<T>("itemlist", resultFunction.get(), compProvider));
×
73
        } else {
74
            lazyLoading = true;
×
75
            add(new MethodResultComponent<List<T>>("itemlist", readyFunction, resultFunction) {
×
76
                @Override
77
                public Component getResultComponent(String markupId, List<T> result) {
78
                    return new ItemList<T>(markupId, resultFunction.get(), compProvider);
×
79
                }
80
            });
81
        }
82
    }
×
83

84
    public ItemListPanel<T> setDescription(String description) {
85
        this.description = description;
×
86
        return this;
×
87
    }
88

89
    public ItemListPanel<T> makeInline() {
90
        add(new AttributeAppender("class", " inline"));
×
91
        return this;
×
92
    }
93

94
    // TODO Improve this (member/admin) button handling:
95
    public ItemListPanel<T> addButton(String label, Class<? extends NanodashPage> pageClass, PageParameters parameters) {
96
        if (parameters == null) parameters = new PageParameters();
×
97
        if (space != null) parameters.add("context", space.getId());
×
98
        AbstractLink button = new BookmarkablePageLink<NanodashPage>("button", pageClass, parameters);
×
99
        button.setBody(Model.of(label));
×
100
        buttons.add(button);
×
101
        return this;
×
102
    }
103

104
    public ItemListPanel<T> addMemberButton(String label, Class<? extends NanodashPage> pageClass, PageParameters parameters) {
105
        if (parameters == null) parameters = new PageParameters();
×
106
        if (space != null) parameters.add("context", space.getId());
×
107
        AbstractLink button = new BookmarkablePageLink<NanodashPage>("button", pageClass, parameters);
×
108
        button.setBody(Model.of(label));
×
109
        memberButtons.add(button);
×
110
        return this;
×
111
    }
112

113
    public ItemListPanel<T> addAdminButton(String label, Class<? extends NanodashPage> pageClass, PageParameters parameters) {
114
        if (parameters == null) parameters = new PageParameters();
×
115
        if (space != null) parameters.add("context", space.getId());
×
116
        AbstractLink button = new BookmarkablePageLink<NanodashPage>("button", pageClass, parameters);
×
117
        button.setBody(Model.of(label));
×
118
        adminButtons.add(button);
×
119
        return this;
×
120
    }
121

122
    public ItemListPanel<T> setSpace(Space space) {
123
        this.space = space;
×
124
        return this;
×
125
    }
126

127
    public ItemListPanel<T> setReadyFunction(ReadyFunction readyFunction) {
128
        this.readyFunction = readyFunction;
×
129
        return this;
×
130
    }
131

132
    @Override
133
    protected void onBeforeRender() {
134
        if (!finalized) {
×
135
            add(new Label("description", description).setVisible(description != null));
×
136
            if (space != null && readyFunction != null && !readyFunction.get()) {
×
137
                add(new AjaxLazyLoadPanel<Component>("buttons") {
×
138

139
                    @Override
140
                    public Component getLazyLoadComponent(String markupId) {
141
                        return new ButtonList(markupId, space, buttons, memberButtons, adminButtons);
×
142
                    }
143

144
                    @Override
145
                    protected boolean isContentReady() {
146
                        return readyFunction.get();
×
147
                    }
148

149
                    @Override
150
                    public Component getLoadingComponent(String id) {
151
                        if (lazyLoading) {
×
152
                            return new Label(id).setVisible(false);
×
153
                        } else {
154
                            return new Label(id, ResultComponent.getWaitComponentHtml(null)).setEscapeModelStrings(false);
×
155
                        }
156
                    }
157

158
                });
159
            } else {
160
                add(new ButtonList("buttons", space, buttons, memberButtons, adminButtons));
×
161
            }
162
            finalized = true;
×
163
        }
164
        super.onBeforeRender();
×
165
    }
×
166

167

168
    public abstract class MethodResultComponent<R> extends ResultComponent {
169

170
        private final transient Supplier<Boolean> readyFunction;
171
        private final transient Supplier<R> resultFunction;
172

173
        public MethodResultComponent(String id, ReadyFunction readyFunction, ResultFunction<R> resultFunction) {
×
174
            super(id);
×
175
            setOutputMarkupId(true);
×
176
            this.readyFunction = readyFunction;
×
177
            this.resultFunction = resultFunction;
×
178
        }
×
179

180
        /**
181
         * {@inheritDoc}
182
         */
183
        @Override
184
        protected boolean isContentReady() {
185
            return readyFunction.get();
×
186
        }
187

188
        /**
189
         * {@inheritDoc}
190
         */
191
        @Override
192
        public Component getLazyLoadComponent(String markupId) {
193
            R result = resultFunction.get();
×
194
            return getResultComponent(markupId, result);
×
195
        }
196

197
        public abstract Component getResultComponent(String markupId, R result);
198

199
    }
200

201
    public static interface ComponentProvider<T> extends Function<T, Component>, Serializable {
202
    }
203

204
    public static interface ApiResultListProvider<T> extends Function<ApiResponse, List<T>>, Serializable {
205
    }
206

207
    public static interface ReadyFunction extends Supplier<Boolean>, Serializable {
208
    }
209

210
    public static interface ResultFunction<X> extends Supplier<X>, Serializable {
211
    }
212

213
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc