How to store system-created to-do list items? - oop

In a to-do list where users have both system-created items and their own items, how would you store the items?
A to-do list can have a mix of items. The system-created items can be modified and deleted just like user-created items. There difference is the titles and description text for the system-created items are initially pulled from a configuration. Many users can have the same system-created items. E.g. if two users want to paint rooms in their houses, they'd both get "buy paint" items.
Option 1
Save the full system-created items (including the title & text) with the user-created items.
Pros: Flexibility for user modifications since the items belong to the user and are not dependent on a central item configuration.
Cons: Lots of redundancy because there will be many users all with the same items.
Option 2
Save references to a configuration for system-created items with the user-created items.
Pros: Flexibility for system modifications since if we want to say "buy X-brand paint" instead of "buy paint", the change is easily reflected for all users with this item.
Cons: System-created items have to persist forever in the configuration even if the item is no longer relevant for new to-do lists because otherwise the user's reference will be broken.
Other options?
Thank you!

My initial thought is - what is your requirement? Your user-flows and project road-map might contain information to inform your design.
From your question "system-created items can be modified and deleted just like user-created items":
This indicates that you are going to have to have a way to track modifications to your 'system-created' templates per user or convert them to 'user-created' messages when they are edited.
This is more complexity than you seem to need
It seems much simpler to create messages from system templates, then have them be regular messages.
A bit of extra storage is not going to break the bank
You have not mentioned any case where you would need to operate over only system-created to-do's. But in this case, you could include created-by metadata.

I think the key here is whether you need to be able to modify a "system todo", and that change to be reflected in all the "user todos"...
If that's a requirement (it sounds sensible to me), your only option is Option 2 - the real con of Option 1 is once you copied the "system todo" as a "user todo", you cannot tell anymore whether they're related...
I'd go for a model similar to this, with 2 entities/tables:
ToDoTemplate
Integer id
String name
String description
ToDoItem
Integer id
ToDoTemplate template
Boolean completed = false
?String name = null
?String description = null
When you create a ToDoItem, you create it based on a ToDoTemplate (it may be a blank template), and you set the name and description as null, reusing the template name/description... Only if the user modifies their own ToDoItem is when you store that value... i.e.
String getName() {
return this.name != null ? this.name : this.template.name;
}
This is the most flexible of the approaches, and the only valid in many situations... Note the con you mention:
Cons: System-created items have to persist forever in the configuration even if the item is no longer relevant for new to-do lists because otherwise the user's reference will be broken.
This is not a con really - as long as there's one ToDoItem that uses a given ToDoTemplate, the template is still relevant, and of course there's no reason to remove it...

Related

Graphql and access to Types Properties depending on some logic

I am new to Graphql and some things still confuse me.
I am working on a project, similar to Todo List.
User may have multiple todo items, some of item's properties must be visible to owner only, some should be public.
So far I came up with two ideas:
1) First is to create two separate types, something like:
ToDoType {
id
name
complete
}
ToDoPrivateType {
id
name
complete
colorGroup
createdAt
...other private properties
}
And access
- ToDoType from root query user {...} and everywhere else, except
- viewer {...} where I will use ToDoPrivateType
It will work but looks a little like double-work,
plus if I retrieve todo lists from standard user root query I will not be able to pull private properties for user's own user.
2) I can also provide access to all properties and set to null properties to which a random user should not have access (like createdAt of other's users) but it also does not look right.
Hope what I am asking is not too confusing.
Do these approaches make sense?
Is there a better way to control access to some properties?
Thanks!

Using Rally.ui.AddNew with details

I've created a Rally.ui.AddNew button to add a new release.
If the user hits "Add with Details" (which is the only active button for releases, you can't add a release without details) I would like certain fields to be set by default when the dialog is opened.
For example, I would like the "Create matching Releases in all child projects" checkbox to be set (if it exists), and I'd like to put a default note in the "Notes" area.
How do I do that? It does not look like the listeners "beforecreate" or "create" are called if the details dialog comes up.
Ideally I'd also like a chance to check these items again with another listener just before the item is created. Do these listeners exist?
The Rally standard editor likely provides only limited capabilities for defaulting field values when instantiated. As an indication, AppSDK1 had the rally.sdk.util.Navigation.popupCreatePage() method, which would accept an object with default values, for example:
// Open Defect editor with Defect default-associated to User Story with OID 12345
rally.sdk.util.Navigation.popupCreatePage("defect", {requirementOid: 12345});
The default key/value pairs that this method accepts were not well-documented. One of Rally's UI Engineers provided me with this list at one time:
rally.sdk.util.Navigation.popupCreatePage defaults keys
User Story:
defaultName
rank
iteration
release
parent
dpyOid {dependency}
Defect:
defaultName
defectSuiteOid {Defect Suites}
testCaseResult
testCase
requirement
iteration
Defect Suite:
defaultName
rank
iteration
Portfolio Item:
defaultName
rank
parent
Task:
workProduct
Test Case:
testfolderOid {Test Folder}
artifactOid {Artifact}
Test Set:
iteration
release
While the above list may not be exhaustive (or even completely accurate anymore), it suggests that the allowed defaults for the standard Rally Editor may not include the "Create matching Releases in all child projects" checkbox or the Notes field.
Nonetheless, it's not immediately apparent to me that there is any method or config for AppSDK2's Rally.ui.AddNew that is an analog in functionality to AppSDK1's rally.sdk.util.Navigation.popupCreatePage() ability to setup default values into the resulting Editor window. Hopefully one of Rally's UI Engineers may have better information to add to this question.
Unfortunately for now not all the built-in fields are defaultable (see Mark W's answer above for the list of pre-fillable fields). Any custom fields are though. You'll want to check out the beforeeditorshow event. You can modify the params there.
addNewComponent.on('beforeeditorshow', function(addNew, params) {
params.defaultName = 'foo';
params.c_MyField = 'bar';
});
Note that if you would just like to create or edit objects you can directly call the methods on Rally.nav.Manager.

Use MVC to create multiple ids and names with the same name but incremented number at the end of name

I want to create multiple entities from a single form with parameters that have the same name. I'm trying to create an array starting with 1 and ending in the max number of items in the array. Does entity framework do this by default.
Example:
PersonName(1): "Bob"
PersonName(2): "John"
PersonName(3): "Mindy"
If I loop through collections using entity framework is there a preferred method for name and id attributes.
Html:
<input name="personname(1)" id="personname(1)" value="Bob" /><br />
<input name="personname(2)" id="personname(1)" value="John" /><br />
<input name="personname(3)" id="personname(1)" value="Mindy" /><br />
Also I noticed that when I use #Html.EditorFor it has some overloaded methods to name the id and name attributes. So would it be recommend to build these using the template name set to empty string, and the
htmlFieldName="personname" + "(" + i + ")";
Or is there a preferred technique?
If you use the Html helpers, it does this for you automatically, especially if you use the EditorTemplates. For example:
#for(int i=0, i<collection.Count; i++)
{
Html.TextBoxFor(m => m.collection[i].Name);
<input type="submit"/>
}
This creates the input elements with the proper indexing. The better way is to simply use editor templates though:
#Html.EditorFor(m => m.collection)
You can loop through the collection using for loop. Appending [index] to personname.
For example:
for(int i = 0; i < personName.Length; i++)
{
<input name="personName[" + i + "]" id="personName_" + i value=personName[i] />
}
Note, that ID value cannot contain brackets, braces or similar, that is why you need to use something like underscore plus index value.
The correct answer is you have to add the parent table as the Model. In every reference to any child fields or child tables's fields you have to refer to this parent model first. All child models must drill down in the EditorFor's HiddenFor's, TextBoxFor's etc... by calling on the parent model first. Without the parent it won't know how to correctly relate to it when its time to perform the save changes or when editing it needs to check the proper references. Both the parent ids and child ids must be listed out in order to combine all tables in a single form and then perform a save changes on the fields. Otherwise it won't include those fields or it will not be able to save that table correctly and not auto generate... yes I said "auto generate" the ids. If you try and auto generate the ids yourself it will make maintenance a nightmare.
There... I filled in all the information a noob will need to surpass the point farmers.
So why is this important? Because if the #Model does not point to the top most object that all other object are related to then it doesn't know how the reference relates. Example would be a Document table. But the Document table might have a foreign key to a Title table. That would be one to one. The Document table would still need to be listed first like so Document.Title.TitleName. In a one to many like in an Author... b/c there might be more than one Author.. you would still list Document first. As in Document.Authors ... author would be a collection so you would loop through each author. But at the very top even in Partials you would still only reference #modelDocument and not the author, that would be after the #Model portion in the content area. If you try and reference just the #model author portion. Now it doesn't understand how it relates to the document and you either have to add the document identifier inside the author table's foreign key for the documentid at some point later downstream after adding the author. This is unfortunate as its not necessary if you just started with the Document to begin with.
Of course this can get a little more complicated b/c you can have more than one document per author so a linking table to a documentauthors table would be preferable here... but still Document table would still be listed at the top of a partial view and even the main view in order to completely place the correct identifiers and names in an html page so that when the form is submitted it properly knows how everything is realted. Also the identifiers should be placed in the html helpers for hidden input fields if they are not to be displayed outwardly to the users.
Now to make it an incremented number of times and to start with a certain grouping... it would require a query string or a posting attributes to send the start and stop range for that group or list of authors, or list of books, or documents or whatever. Since the one to many and many to many relationships should be output in for loops, it can select the correct relationships to retrieve and select also the ones to be displayed using linq for the entity framework which is supplied in a private member variable that allow you to perform database crud ops.
For the point farmers... nothing.

Kentico Ecommerce: getting top selling categories

I am using Kentico 7.0, ecommerce version.
I would like to create a sidebar menu that shows the eshop's top selling product categories. I am a kentico newbie so I am looking around for the correct terminology/guidance so that I can dig deeper.
The ideal approach in my opinion would be to be able to add a field on categories, which is used to filter categories for the menu. This way I can either have some kind of job that updates the fields automatically based on sales, OR provide a manual override for an admin to specify whether a category will show up on the menu. Of course some kind of weight would also be needed to specify menu item ordering.
Which way should I look?
HAve you tried using the "Top N products by sales" web part that is available? you can configure from which part of the content tree (products) it should pull the data - in the Path property you can use also a path expression or macro that is resolved dynamically so the web part can display different products in different sections.
There are many ways to code for Kentico. I personally find the API is a bit clunky and on quite a few occasions I was surprised that a method didn't exist requiring extra calls to get the required results. I do use the Kentico API more when putting data in to Kentico. Pulling it out I use the following.
STORED PROC
Write a SQL stored procedure to get the top X categories - GetTop5Categories.
Look at the COM_* tables, specifically COM_OrderItem, linking OrderItemSKUID back to COM_SKU (or View_COM_SKU_Joined if you need to get to the IA).
This will get you the top selling products with a group by, a count, a top X and an order by.
Then you can link to other tables such as CMS_Category or CMS_Document (depending on how you setup your categories). The bonus of this is that procs are compiled, you do all your data manipulation there (it's what MSSQL specialises in!) and you only send back what you need to in the result set.
DOMAIN (leveraging EF)
I usually create a separate class library project myproject.domain and put an Entity Framework edmx in there mapped back to the Kentico DB. Add the proc to the EDMX, then create a Function Import MyProject_GetTop5Categories from your newly imported proc.
WEB
add a reference to the domain project from your web project, and a 'using at the top of the codebehind of the control.
using myproject.domain;
then in Page_Load for the control:
...
if(!IsPostBack)
{
var entities = new MyProjectModelContainer();
var list = entities.MyProject_GetTop5Categories().ToList();
StringBuilder sb = new StringBuilder("<ul>");
foreach(var category in list)
{
sb.Append("<li><a href='"+category.Link+"'>" + category.Name + "</a></li>");
}
sb.Append("<ul>");
listPlaceHolder = sb.ToString();
}
handwritten so probably a typo or two in there :)
HTH

Eclipse RCP: How to order perspective buttons belonging to different plugins?

My application has 5 plugins. Each plugin has a perspective of it's own and hence each perspective extension definition is under individual plugin's plugin.xml.
Now, I want to control the order in which these perspectives appear in my application. How to do it?
There is one main plugin that holds "ApplicationWorkBenchAdvisor.java". This has initialize() method in which I am iterating through the perspective registry using
PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();
and then appending perspective ids in a comma separated fashion to a String variable (pbar) which is used later like this.
PlatformUI.getPreferenceStore().setDefault(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
When iterating thourgh the perspective registry, I can compare perspective ids and sort it(when adding to 'pbar' by comparing ids) the way I want it to appear but, I don't want to do this ordering here as it appears like a dirty way.
Is there any other place where we can fix the order in which perspectives appear? (Each perspective resides in different plugin).
ADDED
1) Could we also control the ordering in the perspective switcher?
2) Is there a way to control entry into perspective registry to in inflict the desired order. If not could we write back into perspective registry?
If your application is encapsulated as an eclipse product, you may tweak the plugin.properties/plugin_customization.ini file.
(file referenced by the 'preferenceCustomization' property in your product extension point.)
This file is a java.io.Properties format file. Typically this file is used to set the values for preferences that are published as part of a plug-in's public API.
(Example of such a file for org.eclipse.platform)
So if the string representing the order of perspective can be referenced as a property, you can define the default order in there.
Since the source code of IWorkbenchPreferenceConstants mentions:
/**
* Lists the extra perspectives to show in the perspective bar.
* The value is a comma-separated list of perspective ids.
* The default is the empty string.
*
* #since 3.2
*/
public static final String JavaDoc PERSPECTIVE_BAR_EXTRAS = "PERSPECTIVE_BAR_EXTRAS"; //$NON-NLS-1$
Maybe a line in the plugin_customization.ini file:
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
would allow you to specify that order without having to hard-code it.
Additional notes:
IPerspectiveRegistry (or PerspectiveRegistry) is not made to write anything (especially for perspective defined in an extension)
Ordering may be found in the state of the workbench (stored in the workspace and then restored when its launched again, .metadata/.plugins/org.eclipse.ui.workbench/workbench.xml)
Do you confirm that:
IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
IPerspectiveDescriptor[] perspectives = registry.getPerspectives();
is not in the right order when the plugin_customization.ini does define that order correctly ?
Liverpool 5 - 0 Aston Villa does confirm that (in the comments), but also indicates the (ordered) ini file entries internally get recorded into preference store, which means they can be retrieved through the preference store API:
PatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS)
Liverpool 5 - 0 Aston Villa then add:
perspective registry (the initial "PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();" bit) remains unaltered (and unordered).
But, you still can "readily access to ordered list of perspectives" through preference store.
So, for other tasks, instead of iterating though perspective registry (which is still unordered), we can use the ordered variable that stores list of ordered perpective ids.
.
.
.
.
Note: another possibility is to Replace the Perspective-Switcher in RCP apps
=> to:
You can more easily define the order in a menu or in buttons there.
Extreme solution: re-implement a perspective switcher.
To sum up all the observations and findings,
1) It is not possible to alter entries in the perspective registry. It is read-only.
2) To make perspective appear in the order that we want on perspective bar, we can achieve it by adding an entry in plugin_customization.ini (or preferences.ini) as shown below.
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
3) If we want to fetch this ordered list, we can't fetch it directly. But as this ini file entry internally gets recorded in PreferenceStore we can fetch the same value from PreferenceStore using the following API as shown below.
PlatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
Why would someone need to access the entry defined in ini file at all?
Well, in my case I had a view in which i had to display links to every perspective. As my perspective bar was sorted in desired order, I also wanted to maintain the same order in my view while displaying links to perspectives.
4) There is no known way to inflict the same sort order in the display of default perspective switcher. While a new custom perspective switcher can be written to achieve the desired effect.