SharePoint picker API folder name return - sharepoint-online

I am currently implementing a folder picker in our app. The picker uses the OneDrive & SharePoint Javascript picker.
https://learn.microsoft.com/en-us/onedrive/developer/controls/file-pickers/js-v72/open-file?view=odsp-graph-online
Everything is looking good, I can set a root folder etc and get a response. Unfortunately, the response only has the Id of the folder and not the name.
I have tried to use the queryParameters prop to select id, name etc using select=id,name but that does not help at all.
Here is the configuration that is sent to the picker.
this.options = {
clientId: '<ClientID>',
accountSwitchEnabled: false,
action: "query",
multiSelect: true,
viewType: OneDriveViewType.All,
advanced: {
endpointHint: '<SharePoint Link>/Shared%20Documents',
},
success: (folder) => this._onSuccess(folder),
cancel: () => this._onCancel(),
error: (error) => this._onError(error)
}
// Show the picker
OneDrive.open(this.options);
Is there an option that I am missing? As per the docs, the response should contain the "name" property, although it show it for a folder.
https://learn.microsoft.com/en-us/onedrive/developer/controls/file-pickers/js-v72/open-file?view=odsp-graph-online#4-handling-the-picker-response-object

Related

How to integrate react font awesome icon picker in PropertyFieldCollectionData control in SPFx?

I have created SharePoint Framework web part in SharePoint online. I have integrated PropertyFieldCollectionData in that web part. Below is the link for the same,
https://pnp.github.io/sp-dev-fx-property-controls/controls/PropertyFieldCollectionData/
Now, I need to integrate React Font Awesome Icon Picker into PropertyFieldCollectionData control. Below is the link for the same,
https://github.com/DATechnologies/react-fa-icon-picker#readme
I have successfully integrated my SPfx web part. I can select an icon from the icon picker but it is not reflected in the SharePoint page PropertyFieldCollectionData. Below is my code snippet,
PropertyFieldCollectionData("myCollectionData", {
key: "myCollectionData",
value: this.properties.myCollectionData,
fields: [
{
id: "Icon",
title: "Icon (fontawesome)",
type: CustomCollectionFieldType.custom,
required: true,
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
return (
React.createElement(IconPicker, { key: itemId, value: item.customFieldId, onChange: (e) => { value = e, item.customFieldId = e, onUpdate(value, e); } })
);
]
}
Can anyone help me with the same?
Thanks

(NodeJS) Google Drive API - Folder listing modifiedTime

How do I get the date of the last time a folder on google drive has been updated.
For an example, when the last file was copied into it.
Currently I'm using the following code to get back the date when the folder was created:
const drive = google.drive({ version: 'v3', auth});
console.log("Calling listing")
await drive.files.list({
pageSize: 1000,
fields: 'nextPageToken, files(id, name, modifiedTime)',
q: "mimeType='application/vnd.google-apps.folder'",
}, (err, dataResponse) => {
if(err) {
res.json("Error " + err);
}
const folders = dataResponse.data.files;
console.log(folders);
res.json(folders);
})
In agreement with the UI behavior, the Last Modified time the API will give you for the folder itself will be different from the Last Modified time of the latest modified file within this folder
This is due to Google's Drive hierarchy where a change of the Last Modified time of a file does not necessary change the Last Modified time of the parent folder
In any case, if you would like to know the Last Modified time of the folder itself, you need to perform a Files: get request specifying the id of the folder as fileId and setting fields to modifiedTime.
Sample:
...
await drive.files.get({
fileId: "XXX"
fields: "modifiedTime"
},
...
If you would like to access the modifiedTime property of the files in the folder, you can do it with Files: list , setting q to 'XXX' in parents, whereby XXX is the id of the parent folder, and setting fields to files/modifiedTime.
Sample:
...
await drive.files.list({
fields: "files(modifiedTime)",
q: "'XXX' in parents"
}
...
This will return you a response like
{
"files": [
{
"modifiedTime": "2021-10-09T14:22:58.306Z"
},
{
"modifiedTime": "2021-10-07T17:38:56.515Z"
},
{
"modifiedTime": "2021-09-28T16:28:12.476Z"
},
{
"modifiedTime": "2021-09-27T16:13:58.201Z"
}
]
}
You can then programmatically determine the newest timestamp from the result list.

Why User Id gotten from sharepoint siteusers api or clientPeoplePickerSearchUser api different from sharepoint Task AssignedToId?

Im trying to create a task using sharepoint rest api, in doing so Im trying to add assignee as well which is done through adding AssignedToId. The user Id I get for a particular user using the user information api or clientPeoplePickerSearchUser api with site users api (e.g. user retrived with Id 28) is different from what it wants as AssignedToId (AssignedToId it wants is 14) for the same user.
I have tried the api user information api
GET
/_vti_bin/ListData.svc/UserInformationList?$filter=(substringof('" + params.searchKey + "',Name) and ContentType eq 'Person')
And also the clientPeoplePickerSearchUser
POST /_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser
var data = {
queryParams: {
AllowEmailAddresses: true,
AllowMultipleEntities: false,
AllUrlZones: false,
MaximumEntitySuggestions: 50,
PrincipalSource: 15,
PrincipalType: 15,
QueryString: params.searchKey,
Required: false,
UrlZoneSpecified: false
}
}
let users = JSON.parse(createTaskResponse.data.d.ClientPeoplePickerSearchUser)
// return users
let userUrl = this.userProvider.resource + "/_api/web/siteusers?"
let promises = []
for(let user of users) {
let actualUrl = userUrl + "Title eq " + user.DisplayText
console.log('user is: ', user.DisplayText)
promises.push(axios.get(actualUrl, {
headers: headers
}))
}
So the issue with my approach was that sharepoint has differnt user ids across base domain/ site and across subsites, so you want to use the actual site url instaed of the base sharepoint url when accessing sharepoint users.

How to populate custom React component in Keystone Admin

We're using Keystone (version 4.0.0-beta.8) as our Node.js CMS for the first time for a project and we're really liking it. However we're running into a vital missing feature of the CMS and that is adding custom components to the admin views.
What we would like to achieve is to add a custom React component to one of the Keystone admin screens and populate it with data from a field watch function
This component should only be visible for one of the list models. Right now, the only way to do this, is to edit one of the core files:
/node_modules/keystone/admin/client/App/screens/Item/index.js
and add some conditional rendering around it:
{(this.props.params.listId === 'my-list-model') ? (
<MyComponent>{this.props.params.listId}</MyComponent>
) : null }
This works, but is not ideal off-course since you're overwriting core files. But I could overcome this short-come if I knew how I can feed this custom component with data from the Keystone list model declaration:
In: /server/models/MyListModel.js
import keystone from 'keystone';
import { someFunction } from './myFunctions';
var MyListModel = new keystone.List('MyListModel', {
map: { name: 'title' },
});
MyListModel.add({
title: { type: String, required: true },
data: { type: Types.Code, language: 'json', watch: 'title', value: watchTitle, noedit: true },
});
MyListModel.register();
function watchTitle(callback) {
if (this.title) {
function cb(error, result) {
if (result) {
// Send result to React Component in Admin screen
}
callback(error, result);
}
someFunction(this.title, cb);
} else {
callback(null, '');
}
}
Does anyone bump into the same issue or have any clue how to send data to a custom component in the react admin view of Keystone?
Thanks a lot!

Trying to update a mongodb document field via pug/node.js button click

This is a document from my todo mongodb:
"_id" : ObjectId("5a1e96f856f24c43b886eb54"),
"title" : "Drink coffee",
"note" : "Tomorrow morning",
"open" : true,
"duedate" : "2017-12-03"
This is the pug code that populates a todo list page
each todo in todolist
if todo.open
div
a(href="#") #{todo.title}
div
p(style='white-space:pre;')
| #{todo.note}
| Due: #{todo.duedate}
button(id="doneButton") Done
The above works fine. The todo page displays all todo items as expected.
What I want to do:
When user clicks on 'Done' button, I want to update that particular document to "open": false.
(I want to do this onclick, and not by loading the item on a new edit page with an edit button. When todo list page reloads, that todo item is removed from the list. I do not want to delete the document as I need to archive it later on.)
So my questions are:
How do I code the 'Done' button on the pug page so that it gets
associated with the particular document that needs to be updated?
How do I structure the POST code on my index.js so that it listens for
the button click and performs the relevant document update?
UPDATE
OK, so I don't know enough to understand kentor's reply (but thank you anyway!). I did a bit of research though and some copying and pasting, and I have moved the problem a couple of steps forward - I hope.
New pug code:
each todo in todolist
if todo.open
a(href="#") #{todo.title}
p #{todo.note}
p Due: #{todo.duedate}
form#form_update_item(name="updateitem", method='post', action='/updateitem')
input#input_name(type="hidden", placeholder="", name="_id", value="#{todo._id}")
button(type="submit") Done
index.js code
router.post('/updateitem', function(req, res) {
var MongoClient = mongodb.MongoClient;
var ObjectId = require('mongodb').ObjectId;
var url = 'mongodb://localhost:27017/tododb';
MongoClient.connect(url, function(err, db) {
if (err) {
console.log("can't connect", err);
}
else {
console.log('Connected to server. Woohoo!');
var collection = db.collection('todolist');
collection.findOneAndUpdate(
{"title": "Make smoothie"},
{
$set: {
"open": false
}
},
function(err, result) {
if (err) {
console.log(err);
} else {
res.redirect("todolist");
}
db.close();
});
}
});
});
What happens now:
On button click, doc with title "Make Smoothie" changes to "open": false. So button triggers the change I want. Bang! But this is only a partial solution to help me isolate the problem.
What I still need:
On button click, I want the doc's ID whose button was clicked to replace {"title": "Make smoothie"} so that the "open": false change can be made. Something like {_id: "doc ID coming from button blah blah"}.
UPDATE 2
Discovered that I was using Jade syntax not Pug, so instead of this
value="#{todo._id}
I should be using
value=todo._id
So now index.js can console.log the ID the Pug form is passing. Last challenge is to use that ID to change the corresponding mongodb document as described above.
I finally solved it
Last step, I replaced
{"title": "Make smoothie"}
with
{"_id": ObjectId(req.body._id)}
and sure enough, every time I click on a button, the server updates the corresponding document's "open": false
You could just attach a data attribute to the HTML button like this:
button(id="doneButton", data-id=todo._id) Done
Then you would just attach an event listener to this button and send a POST request containing this data-id. Using Jquery it could look like this:
.script
$('#doneButton').on("click", function (element) {
var data = $(this).data("id");
$.ajax({
type: "POST",
url: "your-url",
data: { todoId: data },
success: responseHandler
})
})

Resources