change default theme admin of croogo 2.0 (cakephp)? - cakephp

I try to change the default admin theme for croogo 2.0 ??.. I did all the configuration
existing...but don't work.
thank you to help me
my settings.json
{
"Site": {
"acl_plugin": "Acl",
"admin_theme": "Ace",
"asset_timestamp": "force",
"email": "you#your-site.com",
"feed_url": "",
"home_url": "",
"ipWhitelist": "127.0.0.1",
"locale": "eng",
"status": 1,
"tagline": "A CakePHP powered Content Management System.",
"theme": "Mytheme",
"timezone": 0,
"title": "MyTitle"
},
"Croogo": {
"Api": {
"path": "api"
},
"dashboardUrl": {
"admin":true,
"plugin": "extensions",
"controller": "extensions_dashboard",
"action": "index"
},
"installed": 1,
"version": "2.0.0"
},
"Hook": {
"bootstraps": "Settings,Comments,Contacts,Nodes,Meta,Menus,Users,Blocks,Taxonomy,FileManager,Wysiwyg,Ckeditor"
},
"Access Control": {
"autoLoginDuration": "+1 week",
"models": "",
"multiRole": 0,
"rowLevel": 0
},
"Comment": {
"date_time_format": "M d, Y",
"email_notification": 1,
"feed_limit": 10,
"level": 1
},
"Meta": {
"description": "Croogo - A CakePHP powered Content Management System",
"generator": "Croogo - Content Management System",
"keywords": "croogo, Croogo",
"robots": "index, follow"
},
"Reading": {
"date_time_format": "D, M d Y H:i:s",
"nodes_per_page": 5
},
"Service": {
"akismet_key": "your-key",
"akismet_url": "http://your-blog.com",
"recaptcha_private_key": "your-private-key",
"recaptcha_public_key": "your-public-key"
},
"Writing": {
"wysiwyg": 1
}
}
and I put my theme admin in /public_html/demo/View/Themed/Ace

Related

APL skill without lambda functions

I am creating Alexa echo show skill, I have created one sample Alexa skill without lambda function that hits myserver api and I return response in Alexa accepted format like below:
{
"version": "1.0",
"sessionAttributes": {},
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "My output speech"
},
"card": {
"type": "Simple",
"title": "hELLO",
"content": "Meetings"
},
"reprompt": {
"outputSpeech": {
"type": "PlainText",
"text": "Can I help you with anything else?"
}
},
"shouldEndSession": false
}
}
Till now my skill working fine, But now I want to show a template over the echo show that is possible with APL(Alexa Programming Language).
I am not getting APL examples without lambda function, I have tried to add some APL response json from the example that i got and put into above response json that is not working.
I am confused with APL, Should i just need to add some attribute only in the above response or need to use sdk at my server that is running with PHP whose sdk i did not find at the portal.
Please help me
If you want to send an APL document, you have to send a directive to the JSON
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Hello world, change me</speak>"
},
"directives": [
{
"type": "Alexa.Presentation.APL.RenderDocument",
"token": "TemplateTypescript",
"document": {
"type": "APL",
"version": "1.7",
"license": "Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: LicenseRef-.amazon.com.-AmznSL-1.0\nLicensed under the Amazon Software License http://aws.amazon.com/asl/",
"theme": "dark",
"import": [
{
"name": "alexa-layouts",
"version": "1.4.0"
}
],
"resources": [
{
"description": "Default dimensions, numbers and strings for the AlexaHeadline.",
"dimensions": {
"primaryTextMaxWidth": "100%",
"secondaryTextMaxWidth": "100%",
"secondaryTextTopPadding": "#spacingXSmall",
"contentPaddingLeft": "#marginHorizontal"
},
"numbers": {
"headlinePrimaryTextMaxLines": 2
},
"strings": {
"textComponentAlign": "center"
}
},
{
"description": "Dimensions for the AlexaHeadline - hubLandscapeLarge.",
"when": "${#viewportProfile == #hubLandscapeLarge}",
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions for the AlexaHeadline - hubRound.",
"when": "${#viewportProfileCategory == #hubRound}",
"dimensions": {
"secondaryTextTopPadding": "#spacing3XSmall"
}
},
{
"description": "Dimensions for the AlexaHeadline - tvLandscapeOverlay/tvLandscapeXLarge.",
"when": "${#viewportProfile == #tvLandscapeXLarge || #viewportProfile == #tvLandscapeOverlay}",
"dimensions": {
"primaryTextMaxWidth": "560dp",
"secondaryTextMaxWidth": "560dp",
"secondaryTextTopPadding": "#spacing3XSmall"
}
},
{
"description": "Dimensions for the AlexaHeadline - tvLandscapeXLarge.",
"when": "${#viewportProfile == #tvLandscapeXLarge}",
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - tvPortraitOverlay.",
"when": "${#viewportProfile == #tvPortraitOverlay}",
"dimensions": {
"primaryTextMaxWidth": "220dp",
"secondaryTextMaxWidth": "220dp",
"contentPaddingLeft": "#spacing2XLarge"
},
"strings": {
"textComponentAlign": "left"
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - mobileSmall portrait.",
"when": "${#viewportProfile == #mobileSmall && #viewportOrientation == #viewportOrientationPortrait}",
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - mobileMedium.",
"when": "${#viewportProfile == #mobileMedium}",
"dimensions": {
"primaryTextMaxWidth": "758dp"
},
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - mobileLarge.",
"when": "${#viewportProfile == #mobileLarge}",
"dimensions": {
"primaryTextMaxWidth": "1025dp"
},
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - hubPortraitMedium.",
"when": "${#viewportProfile == #hubPortraitMedium}",
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
},
{
"description": "Dimensions, numbers and strings for the AlexaHeadline - hubLandscapeXLarge.",
"when": "${#viewportProfile == #hubLandscapeXLarge}",
"dimensions": {
"primaryTextMaxWidth": "1440dp"
},
"numbers": {
"headlinePrimaryTextMaxLines": 4
}
}
],
"styles": {
"primaryTextLight": {
"extends": "textStyleDisplay4",
"values": [
{
"color": "#colorTextReversed"
}
]
},
"secondaryTextLight": {
"extends": "textStyleCallout",
"values": [
{
"color": "#colorTextReversed"
}
]
}
},
"layouts": {
"AlexaHeadline": {
"parameters": [
{
"name": "theme",
"description": "Colors will be switched depending on the specified theme (light/dark). Default to dark theme",
"type": "string",
"default": "dark"
},
{
"name": "primaryText",
"description": "Primary message",
"type": "string"
},
{
"name": "secondaryText",
"description": "secondary message",
"type": "string"
},
{
"name": "headerAttributionOpacity",
"type": "number",
"default": "${#viewportProfileCategory == #hubRound ? 1 : #opacitySecondary}"
},
{
"name": "headerTitle",
"description": "Primary text to render in header.",
"type": "string"
},
{
"name": "headerSubtitle",
"description": "Secondary text to render in header.",
"type": "string"
},
{
"name": "headerAttributionText",
"description": "Attribution text to render in header. Only shown when no headerAttributionImage is provided, and when headerAttributionPrimacy is true, or on a device that shows Title/Subtitle and Attribution.",
"type": "string"
},
{
"name": "headerAttributionImage",
"description": "URL for attribution image source. Only shown when headerAttributionPrimacy is true, or on a device that shows Title/Subtitle and Attribution.",
"type": "string"
},
{
"name": "headerAttributionPrimacy",
"description": "On devices that can only display one element due to screen size, Attribution is prioritized. Setting False displays Title/Subtitle. Defaults to true.",
"type": "boolean",
"default": true
},
{
"name": "headerDivider",
"description": "Toggle to display the divider that appears at the bottom of header to help separate it from the content below. Default to false",
"type": "boolean",
"default": false
},
{
"name": "headerBackButton",
"description": "Toggle to display back button in header. Defaults to false.",
"type": "boolean",
"default": false
},
{
"name": "headerBackButtonAccessibilityLabel",
"description": "An accessibility label to describe the back button to customers who use a screen reader.",
"type": "string"
},
{
"name": "headerBackButtonCommand",
"description": "Command that is issued when back button is pressed.",
"type": "any",
"default": {
"type": "SendEvent",
"arguments": ["goBack"]
}
},
{
"name": "headerBackgroundColor",
"description": "Optional color value to use as background color for Header. Defaults to transparent.",
"type": "color",
"default": "transparent"
},
{
"name": "backgroundColor",
"description": "Color value to use as background color for layout.",
"type": "color"
},
{
"name": "backgroundImageSource",
"description": "URL for background image source.",
"type": "string"
},
{
"name": "backgroundVideoSource",
"description": "URL for background video source.",
"type": "any"
},
{
"name": "backgroundScale",
"description": "Image/video scale to apply to background image/video. Defaults to best-fill.",
"type": "string",
"default": "best-fill"
},
{
"name": "backgroundAlign",
"description": "Image/video alignment to apply to background image/video. Defaults to center.",
"type": "string",
"align": "center"
},
{
"name": "backgroundBlur",
"description": "Toggle to apply background blur. Defaults to false.",
"type": "boolean",
"default": false
},
{
"name": "backgroundColorOverlay",
"description": "Toggle to apply overlay scrim to background image/video. Defaults to false.",
"type": "boolean",
"default": false
},
{
"name": "backgroundOverlayGradient",
"description": "Toggle to apply gradient to background image/video. Defaults to false.",
"type": "boolean",
"default": false
},
{
"name": "backgroundVideoAutoPlay",
"description": "Toggle to autoplay background video(s). Defaults to false.",
"type": "boolean",
"default": false
},
{
"name": "backgroundVideoAudioTrack",
"description": "Audio track to play on. Defaults to foreground. EM can select foreground | background | none.",
"type": "string",
"default": "foreground"
},
{
"name": "footerHintText",
"type": "string",
"description": "Hint text to display in Footer."
},
{
"name": "entities",
"description": "Array of entity data bind to this layout",
"type": "any"
},
{
"name": "layoutDirection",
"description": "The layoutDirection of AlexaHeadline. It can be LTR or RTL. By default, it uses environment layoutDirection.",
"type": "string",
"default": "${environment.layoutDirection}"
},
{
"name": "lang",
"description": "The lang property of AlexaHeadline. Set the lang property to a BCP-47 string (e.g., en-US). By default, it uses environment lang.",
"type": "string",
"default": "${environment.lang}"
}
],
"items": [
{
"type": "Container",
"layoutDirection": "${layoutDirection}",
"height": "100vh",
"entities": "${entities}",
"items": [
{
"type": "AlexaBackground",
"backgroundColor": "${backgroundColor}",
"backgroundImageSource": "${backgroundImageSource}",
"backgroundVideoSource": "${backgroundVideoSource}",
"backgroundScale": "${backgroundScale}",
"backgroundAlign": "${backgroundAlign}",
"backgroundBlur": "${backgroundBlur}",
"colorOverlay": "${backgroundColorOverlay}",
"overlayGradient": "${backgroundOverlayGradient}",
"videoAutoPlay": "${backgroundVideoAutoPlay}",
"videoAudioTrack": "${backgroundVideoAudioTrack}"
},
{
"type": "Container",
"height": "100vh",
"width": "100vw",
"position": "absolute",
"items": [
{
"type": "Container",
"grow": 1,
"justifyContent": "center",
"paddingLeft": "#contentPaddingLeft",
"paddingRight": "#marginHorizontal",
"alignItems": "center",
"items": [
{
"when": "${primaryText && primaryText != ''}",
"type": "Text",
"style": "${theme == 'light' ? 'primaryTextLight' : 'textStyleDisplay4'}",
"text": "${primaryText}",
"opacity": 1,
"textAlign": "#textComponentAlign",
"maxWidth": "#primaryTextMaxWidth",
"maxLines": "#headlinePrimaryTextMaxLines"
},
{
"when": "${secondaryText && secondaryText != ''}",
"type": "Text",
"style": "${theme == 'light' ? 'secondaryTextLight' : 'textStyleCallout'}",
"text": "${secondaryText}",
"maxLines": 1,
"opacity": "#opacitySecondary",
"textAlign": "#textComponentAlign",
"maxWidth": "#secondaryTextMaxWidth",
"paddingTop": "#secondaryTextTopPadding"
}
]
},
{
"type": "AlexaHeader",
"theme": "${theme}",
"headerTitle": "${headerTitle}",
"layoutDirection": "${layoutDirection}",
"headerSubtitle": "${#viewportProfile != #tvLandscapeOverlay ? headerSubtitle : ''}",
"headerAttributionText": "${headerAttributionText}",
"headerAttributionImage": "${headerAttributionImage}",
"headerAttributionPrimacy": "${headerAttributionPrimacy}",
"headerDivider": "${headerDivider}",
"headerBackButton": "${headerBackButton}",
"headerBackButtonAccessibilityLabel": "${headerBackButtonAccessibilityLabel}",
"headerBackButtonCommand": "${headerBackButtonCommand}",
"headerBackgroundColor": "${headerBackgroundColor}",
"headerAttributionOpacity": "${headerAttributionOpacity}",
"position": "absolute",
"width": "100%",
"top": "0"
},
{
"when": "${#viewportProfileCategory != #hubRound && #viewportProfile != #tvLandscapeOverlay && footerHintText}",
"type": "AlexaFooter",
"hintText": "${footerHintText}",
"theme": "${theme}",
"lang": "${lang}",
"position": "absolute",
"width": "100%",
"bottom": "0"
}
]
}
]
}
]
}
},
"mainTemplate": {
"parameters": ["payload"],
"item": [
{
"type": "AlexaHeadline",
"id": "PlantHeadline",
"primaryText": "${payload.headlineTemplateData.properties.textContent.primaryText.text}",
"headerBackButton": false,
"headerAttributionImage": "${payload.headlineTemplateData.properties.logoUrl}",
"headerAttributionPrimacy": true,
"footerHintText": "${payload.headlineTemplateData.properties.hintText}",
"backgroundImageSource": "${payload.headlineTemplateData.properties.backgroundImage.sources[0].url}",
"backgroundColorOverlay": false,
"speech": "${payload.headlineTemplateData.properties.welcomeSpeech}",
"theme": "light"
}
]
},
"onMount": [
{
"type": "SpeakItem",
"componentId": "PlantHeadline"
}
]
},
"datasources": {
"headlineTemplateData": {
"type": "object",
"objectId": "headlineSample",
"properties": {
"backgroundImage": {
"sources": [
{
"url": "https://d2o906d8ln7ui1.cloudfront.net/images/templates_v3/headline/HeadlineBackground_Light.png",
"size": "large"
}
]
},
"textContent": {
"primaryText": {
"type": "PlainText",
"text": "Welcome to Template Typescript"
}
},
"logoUrl": "",
"hintText": ""
}
}
},
"timeoutType": "SHORT"
}
],
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Hello world, change me</speak>"
}
},
"shouldEndSession": false,
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-node/2.11.0 Node/v12.22.4"
}
}
You can use https://apl.ninja/ or within the developer console to help you get started quickly.

Mock service worker with openApi backend

I am working with MSW and OpenAPI-backend package.
I want to mock the booth browser server and test server.
I have OpenAPI definition available form with I generate generated.ts for RTK Query (out of scope for this question). I want to use OpenAPI spec to use it with OpenAPI Backend and generate MSW rest worker for browser and for test.
Setup is next:
index.tsx
import worker from './mocks/browser';
if (process.env.NODE_ENV === 'development') {
worker.start();
}
mock/browser.ts
import { setupWorker, rest } from 'msw';
import { OpenAPIBackend } from 'openapi-backend';
import type { Document } from 'openapi-backend';
import definition from './api.json';
// create our mock backend with openapi-backend
const api = new OpenAPIBackend({ definition: definition as Document });
api.register('notFound', (c, res, ctx) => res(ctx.status(404)));
api.registerHandler('notImplemented', async (c, req, res) => {
const { status, mock } = await api.mockResponseForOperation(
c.operation.operationId as string
);
return res.status(status).json(mock);
});
api.register('validationFail', (c, res, ctx) =>
res(ctx.status(400), ctx.json({ error: c.validation.errors }))
);
const worker = setupWorker(
rest.get('/*', (req) =>
api.handleRequest({
...req,
path: req.url.pathname,
headers: req.headers.all(),
method: req.method,
body: req.body,
})
)
);
export default worker;
api.JSON
{
"openapi": "3.0.1",
"info": {
"title": "Fetch API",
"description": "Source of truth for Fetch dashboard",
"version": "0.1.5"
},
"paths": {
"/config": {
"get": {
"tags": [
"Configuration"
],
"summary": "Retreive configuration object",
"description": "Returns configuration object (map) containing configuration parameters for UI (Map<String, String>)",
"responses": {
"200": {
"description": "successfull operation",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Map serialized to json object.",
"example": {
"FA_COLOR": "red",
"FA_NAME": "fetch"
}
}
}
}
}
}
}
},
"/links": {
"get": {
"tags": [
"Notifications & Links",
"Walking Skeleton"
],
"summary": "List all defined links for hospital",
"description": "Retreives all defined links for hospital. Hospital ID is indirectly obtained from user identity.",
"responses": {
"200": {
"description": "successfull operation",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
}
}
},
"/kpis": {
"get": {
"tags": [
"KPIS"
],
"summary": "List all KPIs for hospital(s) that current user is managing.",
"description": "Retreives all KPIs available for hospitals that current user is managing.",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/KPI"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"KPI": {
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"revenue",
"labour"
]
},
"hospital_id": {
"type": "string",
"description": "id of hospital that this KPI describes"
},
"goal": {
"type": "number",
"description": "full month goal"
},
"actual": {
"type": "number",
"description": "actual result"
},
"mtd_goal": {
"type": "number",
"description": "month to date goal, so that we can track projected fulfillment of goal."
},
"details": {
"type": "object",
"description": "Semi-structured way of describing details of calculation. Every KPI will potentialiy be described differently."
}
},
"required": [
"id",
"hospital_id",
"goal",
"actual",
"mtd_goal"
]
},
"Link": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "unique id of link"
},
"hospital_id": {
"type": "string",
"description": "id of hospital that this Link is configured for"
},
"title": {
"type": "string",
"description": "human readable title for URL"
},
"description": {
"type": "string",
"description": "Description of current link (alt text , or tooltip)"
},
"url": {
"type": "string",
"description": "Location of external resource"
},
"urgent": {
"type": "boolean",
"description": "Is urgency of notification elevated?"
},
"count": {
"type": "number",
"description": "Actual notification value. How many 'tasks' are waiting manager in external system."
},
"updated_at": {
"type": "integer",
"description": "Date/time of last notification update",
"format": "int64"
},
"children": {
"type": "array",
"description": "Since notifications are possibly presented in hierarchy all children of this notification will be gathered here",
"items": {
"$ref": "#/components/schemas/Link"
}
}
},
"required": [
"id",
"hospital_id",
"title",
"url"
],
"example": [
{
"id": 1,
"hospital_id": "001",
"title": "Link1",
"description": "description of Link1",
"url": "https://www.example.com/link1",
"urgent": true,
"count": 1,
"updated_at": 1631113184221,
"children": [
{
"id": 2,
"hospital_id": "001",
"title": "Link2",
"description": "description of Link2",
"url": "https://www.example.com/link2",
"urgent": true,
"count": 1,
"updated_at": 1631113184221
}
]
},
{
"id": 3,
"hospital_id": "002",
"title": "Link3",
"description": "description of Link3",
"url": "https://www.example.com/link3",
"urgent": false,
"count": 2,
"updated_at": 1631113184221
}
]
}
}
}
}
component.tsx
const { data: links, error, isLoading } = useGetLinksQuery({});
Which is fethcing localhost:3000/links
Error I am getting is:
mockServiceWorker.js:222 [MSW] Uncaught exception in the request handler for "GET http://localhost:3000/links":
Error: Unknown operation
at OpenAPIValidator.validateRequest (http://localhost:3000/static/js/vendors~main.chunk.js:63911:13)
at OpenAPIBackend.<anonymous> (http://localhost:3000/static/js/vendors~main.chunk.js:54246:45)
at async OpenAPIBackend.handleRequest (http://localhost:3000/static/js/vendors~main.chunk.js:54152:22)
This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses
getResponse # mockServiceWorker.js:222
async function (async)
getResponse # mockServiceWorker.js:175
handleRequest # mockServiceWorker.js:113
async function (async)
handleRequest # mockServiceWorker.js:112
(anonymous) # mockServiceWorker.js:271
Network tabs give:
Request URL: http://localhost:3000/links
Request Method: GET
Status Code: 500 (from service worker)
Referrer Policy: strict-origin-when-cross-origin
All related to article: https://dev.to/epilot/testing-react-with-jest-and-openapi-mocks-8gc
and https://testing-library.com/docs/react-testing-library/example-intro/
Thank you.
In your OpenApi u don't have any operationId.
You need to setup a unique Id by route.
{
"openapi": "3.0.1",
"info": {
"title": "Fetch API",
"description": "Source of truth for Fetch dashboard",
"version": "0.1.5"
},
"paths": {
"/config": {
"get": {
"tags": [
"Configuration"
],
"operationId": "config",
"summary": "Retreive configuration object",
"description": "Returns configuration object (map) containing configuration parameters for UI (Map<String, String>)",
"responses": {
"200": {
"description": "successfull operation",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Map serialized to json object.",
"example": {
"FA_COLOR": "red",
"FA_NAME": "fetch"
}
}
}
}
}
}
}
},
"/links": {
"get": {
"tags": [
"Notifications & Links",
"Walking Skeleton"
],
"operationId": "links",
"summary": "List all defined links for hospital",
"description": "Retreives all defined links for hospital. Hospital ID is indirectly obtained from user identity.",
"responses": {
"200": {
"description": "successfull operation",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
}
}
},
"/kpis": {
"get": {
"tags": [
"KPIS"
],
"summary": "List all KPIs for hospital(s) that current user is managing.",
"description": "Retreives all KPIs available for hospitals that current user is managing.",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/KPI"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"KPI": {
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"revenue",
"labour"
]
},
"hospital_id": {
"type": "string",
"description": "id of hospital that this KPI describes"
},
"goal": {
"type": "number",
"description": "full month goal"
},
"actual": {
"type": "number",
"description": "actual result"
},
"mtd_goal": {
"type": "number",
"description": "month to date goal, so that we can track projected fulfillment of goal."
},
"details": {
"type": "object",
"description": "Semi-structured way of describing details of calculation. Every KPI will potentialiy be described differently."
}
},
"required": [
"id",
"hospital_id",
"goal",
"actual",
"mtd_goal"
]
},
"Link": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "unique id of link"
},
"hospital_id": {
"type": "string",
"description": "id of hospital that this Link is configured for"
},
"title": {
"type": "string",
"description": "human readable title for URL"
},
"description": {
"type": "string",
"description": "Description of current link (alt text , or tooltip)"
},
"url": {
"type": "string",
"description": "Location of external resource"
},
"urgent": {
"type": "boolean",
"description": "Is urgency of notification elevated?"
},
"count": {
"type": "number",
"description": "Actual notification value. How many 'tasks' are waiting manager in external system."
},
"updated_at": {
"type": "integer",
"description": "Date/time of last notification update",
"format": "int64"
},
"children": {
"type": "array",
"description": "Since notifications are possibly presented in hierarchy all children of this notification will be gathered here",
"items": {
"$ref": "#/components/schemas/Link"
}
}
},
"required": [
"id",
"hospital_id",
"title",
"url"
],
"example": [
{
"id": 1,
"hospital_id": "001",
"title": "Link1",
"description": "description of Link1",
"url": "https://www.example.com/link1",
"urgent": true,
"count": 1,
"updated_at": 1631113184221,
"children": [
{
"id": 2,
"hospital_id": "001",
"title": "Link2",
"description": "description of Link2",
"url": "https://www.example.com/link2",
"urgent": true,
"count": 1,
"updated_at": 1631113184221
}
]
},
{
"id": 3,
"hospital_id": "002",
"title": "Link3",
"description": "description of Link3",
"url": "https://www.example.com/link3",
"urgent": false,
"count": 2,
"updated_at": 1631113184221
}
]
}
}
}
}

400 Bad Request on Alexa AddOrUpdateReport using JSON from documentation

My issue is basically described in title but I'll add a little bit more details here.
I'm trying to proactively send an update report to Alexa's Event Hub for Smart Home skills, however this fails with a 400 Bad Request error, and this is what the server responds:
{
"header": {
"namespace": "System",
"name": "Exception",
"messageId": "a154410c-2364-4c5b-9028-accde5048e1e"
},
"payload": {
"code": "INVALID_REQUEST_EXCEPTION",
"description": "Event or endpoint is missing in the request."
}
}
I decided then to check if my request was wrong by sending the one that can be found on their documentation, and I'm getting the very same error.
This is the JSON copied from Amazon's documentation (I just replaced device metadata and the token):
{
"event": {
"header": {
"namespace": "Alexa.Discovery",
"name": "AddOrUpdateReport",
"payloadVersion": "3",
"messageId": "5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4"
},
"payload": {
"endpoints": [
{
"endpointId": "<unique ID of the endpoint>",
"manufacturerName": "Sample Manufacturer",
"description": "Smart Light by Sample Manufacturer",
"friendlyName": "Kitchen Light",
"additionalAttributes": {
"manufacturer" : "Sample Manufacturer",
"model" : "Sample Model",
"serialNumber": "<the serial number of the device>",
"firmwareVersion" : "<the firmware version of the device>",
"softwareVersion": "<the software version of the device>",
"customIdentifier": "<your custom identifier for the device>"
},
"displayCategories": [
"LIGHT"
],
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa.PowerController",
"version": "3",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa.BrightnessController",
"version": "3",
"properties": {
"supported": [
{
"name": "brightness"
}
],
"proactivelyReported": true,
"retrievable": true
}
}
],
"connections": [
],
"cookie": {
}
}
],
"scope": {
"type": "BearerToken",
"token": "access-token-from-Amazon"
}
}
}
}
What I don't understand is why it reports that event or endpoints are missing if they're clearly there and if this JSON is the one that they provide in their documentation.
Does anyone have this issue too?
EDIT: pasting my payload as requested.
{
"event": {
"header": {
"namespace": "Alexa.Discovery",
"name": "AddOrUpdateReport",
"payloadVersion": "3",
"messageId": "132137185729061389"
},
"payload": {
"endpoints": [
{
"endpointId": "Rmxvb2RTZW5zb3JfMDE=",
"friendlyName": "Flood sensor",
"description": "Flood sensor",
"manufacturerName": "MyCompany",
"displayCategories": [
"ACTIVITY_TRIGGER"
],
"cookie": {
"DeviceType": "FloodSensor"
},
"capabilities": [{
"interface": "Alexa",
"type": "AlexaInterface",
"version": "3"
},
{
"interface": "Alexa.EndpointHealth",
"type": "AlexaInterface",
"version": "3",
"properties": {
"supported": [{
"name": "connectivity"
}],
"proactivelyReported": true,
"retrievable": true
}
}
]
}
],
"scope": {
"type": "BearerToken",
"token": "<redacted>"
}
}
}
}

Allow SOLR core only for a single user

I can't find any information on how to allow access to specific SOLR core just for a single user. I am using SOLR7. This is what I've got:
security.json
{
"authentication": {
"blockUnknown": true,
"class": "solr.BasicAuthPlugin",
"credentials": {
"test_admin": "xxx",
"infographics": "xxx",
"test_user": "xxx"
},
"": {
"v": 0
}
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [
{
"name": "all",
"role": "admin",
"index": 1
},
{
"name": "update",
"role": "general",
"index": 2
},
{
"name": "read",
"role": [
"general",
"infographics",
"test_user"
],
"index": 3
},
{
"name": "collection-admin-read",
"role": "general",
"index": 4
},
{
"name": "core-admin-read",
"role": "general",
"index": 5
},
{
"name": "core-specific-permission",
"collection": "test-core",
"role": "test_user",
"before": 3,
"index": 6
}
],
"user-role": {
"test_admin": [
"admin",
"general"
],
"infographics": "infographics",
"test_user": "test_user"
},
"": {
"v": 0
}
}
}
I've added a permission for collection "test-core":
{
"name": "core-specific-permission",
"collection": "test-core",
"role": "test_user",
"before": 3,
"index": 6
}
I authenticate with test_user when calling: /solr/test-core/select?q=*:*, this works fine, but it also can access other cores, for e.g.: /solr/other-core/select?q=*:*.
If I remove test_user from read permission:
{
"name": "read",
"role": [
"general",
"infographics"
],
"index": 3
},
then I am not able to query any core. Getting 403. For test_user I'd like to allow access to only this core /solr/test-core/select?q=*:* and nothing else. Any idea how can I achieve this?

Multi-dimensional arrays in Mandrill with handlebars

I'm trying to loop through a multi-dimensional array to get properties of products that are part of line items. They look basically like this: (I did a json_encode so it would be easier to read)
[{
"rcpt": "email#email.com",
"vars": [{
"name": "SYSTEM",
"content": "Bikes"
}, {
"name": "CUSTOMERSERVICE",
"content": "(855-553-4889)"
}, {
"name": "IMAGE",
"content": "http:\/\/www.url.com\/assets\/images\/chicago\/email\/dear_member.jpg"
}, {
"name": "LINKCOLOR",
"content": "#3db7e4"
}, {
"name": "FACEBOOK",
"content": "Bikes"
}, {
"name": "TWITTER",
"content": "Bikes"
}, {
"name": "INSTAGRAM",
"content": "Bikes"
}, {
"name": "CLOSING",
"content": "Greetings"
}, {
"name": "item",
"content": [{
"lineItem": 1,
"id": "3",
"name": "24-Hour Pass Gift Certificate",
"quantity": 2,
"nameShort": "24-Hour",
"type": "Gift Certificate",
"image": "24hour_blank.jpg",
"price": "9.95",
"total": "19.90",
"taxable": false,
"giftCertificates": {
"3204": {
"id": "3204",
"redemptionNumber": "xxxxx",
"type": "24-Hour"
},
"3205": {
"id": "3205",
"redemptionNumber": "xxxxx",
"type": "24-Hour"
}
}
}, {
"lineItem": 2,
"id": "1",
"name": "Annual Membership Gift Certificate",
"quantity": 2,
"nameShort": "Annual",
"type": "Gift Certificate",
"image": "annual_blank.jpg",
"price": "75.00",
"total": "150.00",
"taxable": false,
"giftCertificates": {
"892": {
"id": "892",
"redemptionNumber": "xxxxxx",
"type": "Annual"
},
"893": {
"id": "893",
"redemptionNumber": "xxxxx",
"type": "Annual"
}
}
}]
}, {
"name": "orderID",
"content": 1220
}, {
"name": "giftMessage",
"content": false
}, {
"name": "email",
"content": "email#email.com"
}, {
"name": "transactionDate",
"content": "12\/23\/2015"
}, {
"name": "transactionTime",
"content": "12:21 pm"
}, {
"name": "salesTaxTotal",
"content": 0
}, {
"name": "salesTaxRatePercent",
"content": "6.250"
}, {
"name": "TransactionAmount",
"content": "169.90"
}, {
"name": "account_number",
"content": "XXXX1111"
}, {
"name": "card_type",
"content": "Visa"
}, {
"name": "firstName",
"content": "tetete"
}, {
"name": "lastName",
"content": "tethuhhu"
}, {
"name": "address",
"content": "295 Place St"
}, {
"name": "city",
"content": "Brooklyn"
}, {
"name": "state",
"content": "NY"
}, {
"name": "zip",
"content": "11238"
}, {
"name": "country",
"content": "US"
}, {
"name": "phone",
"content": "8888888888"
}, {
"name": "transactionId",
"content": "xxxxxx"
}, {
"name": "shipToFirstName",
"content": "tetete"
}, {
"name": "shipToLastName",
"content": "tethuhhu"
}, {
"name": "shipToAaddress",
"content": "295 Place St"
}, {
"name": "shipToCity",
"content": "Brooklyn"
}, {
"name": "shipToState",
"content": "NY"
}, {
"name": "shipToZipCode",
"content": "11238"
}, {
"name": "ShipToCountry",
"content": "US"
}, {
"name": "ShipToCountry",
"content": "US"
}]
}]
So I am trying to get a print out of each gift certificate's type and redemption number. When I iterate through {{ giftCertificates }} like this:
{{#each giftCertificates}}
{{type}} {{redemptionNumber}}
{{/each}}
I get one of the line items but not the other. I'm guessing maybe it is being overwritten when it loops through again? But I have also tried to loop through {{ item }} and grab {{ giftCertificates.type }} and {{ giftCertificates.redemptionNumber }} and that does not work either. What is the correct way to get all of these from each line item?
Thanks for your help.
I know this is a very old question, but:
you can use {{this.proprietyName}} to get the type and number:
{{#each giftCertificates}}
{{this.892.type}}
{{/each}}
do not forget to add this to the mandrill message o
"merge": true,
"merge_language": "handlebars",
Also, the data structure is not ideal:
giftCertificates[
{
"id": "892",
"redemptionNumber": "xxxxxx",
"type": "Annual"
},
{
"id": "893",
"redemptionNumber": "xxxxxx",
"type": "Annual"
}
]
would be easier to handle.

Resources