Unique field types and specific GET-parameters for api calls in Apostrophe CMS - api

I have several questions about Apostrophe CMS:
Is it possible to add a unique field type in apostrophe-pieces? I can't find a way to do this.
Edit: I noticed that I wasn't specific enough. I want to make sure that there can't be two instances in the database with the same value in an added field. It should be something like an additional id. Is there an option for this? Maybe something like:
addFields: [
{
name: 'secondId',
label: 'Second ID',
type: 'string',
required: true,
unique: true
}
]
I want to access the apostrophe-headless api and get a specific element by passing a certain value of one of the created field types of the correspondent piece in a GET-parameter. Is something like this possible?
For example:
Piece:
module.exports = {
extend: 'apostrophe-pieces',
name: 'article',
label: 'Article',
pluralLabel: 'Articles',
restApi: {
safeFor: 'manage'
},
addFields: [
{
name: 'title',
label: 'Name',
type: 'string',
required: true
},
{
name: 'author',
label: 'Author',
type: 'string',
required: true
}
]
};
Desired api call for getting all articles which have strored "Jon" as author:
http://example.com/api/v1/article?author=Jon
Thank you very much in advance!

Custom field types
You can add custom field types at project level by extending apostrophe-schemas and adding the proper definition. You'll need to add a converter for server-side sanitization and a populator for the front-end of the form field.
You can follow the examples in Apostrophe's schema module, linked are the functions defining a float
https://github.com/apostrophecms/apostrophe/blob/0bcd5faf84bc7b05c51de7331b17f5929794f524/lib/modules/apostrophe-schemas/index.js#L1367
https://github.com/apostrophecms/apostrophe/blob/0bcd5faf84bc7b05c51de7331b17f5929794f524/lib/modules/apostrophe-schemas/public/js/user.js#L991
You would add your definitions in your project level lib/modules/apostrophe-schemas's index.js and public/js/user.js respectively.
Filtering
You can search your piece index for a string like Jon by adding ?search=jon to your query but more likely you want to filter pieces by the value of a join.
If you had piece types article and authors, you could have a joinByOne field in article's schema that lets you relate that article to an author piece. Then, by enabling pieceFilters you could filter directly on those joined properties.
A complete rundown of piecesFilters can be found here https://apostrophecms.org/docs/tutorials/intermediate/cursors.html#filtering-joins-browsing-profiles-by-market
I think you'd also need to mark that filter as safe for api use in your apostrophe-headless configuration https://github.com/apostrophecms/apostrophe-headless#filtering-products

Related

Is it possible to query document schema metadata in Sanity/GROQ?

I have a simple singleton document schema defined in my Sanity/NextJS project, to model my "Colophon" page (richText is a custom block field type):
export default {
title: 'Colophon',
name: 'colophon',
type: 'document',
__experimental_actions: ['update', 'publish'],
fields: [
{
title: 'Body',
name: 'body',
type: 'richText',
validation: Rule => Rule.required(),
},
],
};
I retrieve this document with a simple query in my NextJS application:
export async function getStaticProps() {
const colophon = await client.fetch(`
*[_type == "colophon"][0]
`);
// ...
};
Is it possible to write a GROQ query to retrieve the meta title defined in the schema, i.e. Colophon? Although this is a singleton document, I would like to avoid repeating this string in my project if possible. At the moment, I can only see the fields on the document in my results, i.e. body.
Thanks for reading!
No, I don't believe there is.
As far as I understand what you're after; The schema is defined in the studio-instance and not the datastore. Those two are not hard coupled. I have several studio-instances with small variations on the schemas using one single project/datastore. The API you query to get data does not care which studio and schema was used and cant answer for the actual schema details.

ExtJS (4.1) creating static data store

I am no JS star so I'm having trouble finding a solution to something that is probably easier than I know.
the page loads, but the ui content stops when it hits the ui code to load the static store data. The preexisting project uses dynamically grabbed data from the database but this just needs a small list of options. (I miss the days of just using HTML). Firebug shows a non-helpful error in ext-all.js that q is undefined, but since that's obfuscated well maintained code I'm sure it's a problem in my code. Do I need to define the proxy for this even if it's static data? Thank you ahead of time!
Here is the model, store, and ui code
//model
Ext.define('HITS.model.ComboBox', {
extend: 'Ext.data.Model',
fields: [
{type: 'string', name: 'label', mapping: 'label'},
{type: 'string', name: 'value', mapping: 'value'}
]
});
//store
Ext.define('HITS.store.ReportType', {
extend: 'Ext.data.Store',
model: 'HITS.model.ComboBox',
storeId:'ReportType',
data: [
{label:'All Tags', value: 'AllTags'},
{label:'Key Findings', value: 'KeyFindings'}
]
});
//ui
<ui:ComboBox
renderTo="ui_report_list"
fieldLabel="Report:"
inputId="reportSelect"
store="ReportType">
The solution had a couple of changes required. The first was the "value" column, which is of course a reserved word in the database(oracle). The other was because I didn't add some prefunction comments for the model that trigger autogenerated code(I hate this practice).
The code here should mostly work but you'd need the model I ended up using. If you check sencha and don't use reserved words you should be ok.

rally search user by first character

I want to realize the functionality that we can search the users' name by typing in the first character of their names. I need to use Javascript to create a custom html.
Is there anyone who has done this before could help me?
In the example from this repository, a user combobox Rally.ui.combobox.UserComboBox searches for matching values dynamically based on the first couple of characters.
This default functionality displays the expected values after the second character is entered.
var u = Ext.create('Rally.ui.combobox.UserComboBox',{
id: 'u',
project: project,
fieldLabel: 'select user',
listeners:{
ready: function(combobox){
this._onUserSelected(combobox.getRecord());
},
select: function(combobox){
this._onUserSelected(combobox.getRecord());
},
scope: this
}
});
this.add(u);
},
If you want to load all users (do not limit the selection to team members and editors of a specific project) you may use Rally.ui.combobox.Combobox instead of Rally.ui.combobox.UserComboBox, and set the model to User. But to workaround a default behavior where only the current user populates the combobox, use a filter that would filter in all users. In the example below ObjectID > 0 is used. This combobox will be populated by all users independently of the project picker. This fragment is not a part of a custom app example above:
{
xtype: 'rallycombobox',
fieldLabel: 'select project',
storeConfig: {
autoLoad: true,
model: 'User',
filters:[
{
property: 'ObjectID',
operator: '>',
value: 0
}
],
sorters: [
{
property: 'UserName',
direction: 'ASC'
}
]
}
}
You'll want to use the Web Services API. Here's how I would do it...
The API doesn't allow you to specify a placement of a character in the filter, but you can require that it exists somewhere in the name, that filter would look like:
[{
property : "FirstName",
operator : "contains",
value : "A" //Whatever letter you're looking to start with
}]
Now, once the store is loaded, use a second function to filter the records to only those which start with your character:
store.filterBy(function(item) {
return item.get("FirstName")[0] === "A";
});
Hope this helps :)

Array as store in list in sencha touch

Can we use Array Instead of Store for List in "sencha touch".
config:{
store: 'storeName',
scrollable: true,
itemTpl: '<div>{store_id}</div>'
}
This is config part of my store I want to use array for this list instead of store.
Please provide some code.
Thanks.
You can use a List's data config property, which is an array of any fields you want, with some that will match your itemTpl for display. It's basically a direct line into a List's store, which is created in the background for you without needing to be set. You will not need to define the store when setting the data directly.
It's probably best to set the data as an array in a defined store, and then set the store to the list, but you don't have to do it this way, and there are some cases you want to just use a simple array (see example below).
The Sencha Touch documentation shows examples of using the data array without a defined store here.
Sencha Touch 2.1.1 List data example
Ext.create('Ext.List', {
fullscreen: true,
itemTpl: '{title}',
data: [
{ title: 'Item 1' },
{ title: 'Item 2' },
{ title: 'Item 3' },
{ title: 'Item 4' }
]
});
You could also set data to an externally defined array, provided your list is created after the array is. If this turns out to be a timing problem, then you can set the data with an array at any later time using
listname.setData(someArray);
Provided you got a proper reference to listname ahead of time.

SDK 2: % done column

I'd like to use a % done field that uses the same functionality as % done by story plan estimate for portfolio items, except for another field.
What I'd like to do is create the same sort of bar for defects which have been marked as must fix for a particular release, and then show % done by plan estimate. I can handle getting the list of defects, calculating % done etc.
Can you show me an example of how to display such a column?
We have a PercentDoneTemplate in the SDK 2.0p3 release, but it is currently private in the SDK. You can use it, but at the risk of us changing it on you in the future. We are considering making it a publicly supported component. To use it in a grid, you just need to add a templatecolumn column to your columnCfg, something like this:
this.add({
xtype: 'rallygrid',
store: myStore,
columnCfgs: [{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.PercentDoneTemplate')
}]
});
The template is expecting your data to have a field called percentDone (case sensitive). You can change that by adding a config option for percentDoneName
{
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.PercentDoneTemplate', {
percentDoneName: 'myPercentDoneField'
}),
}
It should end up looking like:
If you can calculate the percentage as a decimal, then you can easily generate a rallypercentdone component. However, I don't know how you expect to place them in a column. Perhaps a Rally dev will be able to better assist you in that regard.
https://rally1.rallydev.com/apps/2.0p2/doc/#!/api/Rally.ui.PercentDone