1 | import { body, headers } from "@pnp/queryable";
|
2 | import { getGUID, hOP, stringIsNullOrEmpty, objectDefinedNotNull, combine, isUrlAbsolute, isArray } from "@pnp/core";
|
3 | import { Item } from "../items/types.js";
|
4 | import { _SPQueryable, SPQueryable, SPCollection } from "../spqueryable.js";
|
5 | import { List } from "../lists/types.js";
|
6 | import { odataUrlFrom } from "../utils/odata-url-from.js";
|
7 | import { Web } from "../webs/types.js";
|
8 | import { extractWebUrl } from "../utils/extract-web-url.js";
|
9 | import { Site } from "../sites/types.js";
|
10 | import { spPost } from "../operations.js";
|
11 | import { getNextOrder, reindex } from "./funcs.js";
|
12 | import "../files/web.js";
|
13 | import "../comments/item.js";
|
14 | import { createBatch } from "../batching.js";
|
15 |
|
16 |
|
17 |
|
18 | export var PromotedState;
|
19 | (function (PromotedState) {
|
20 | |
21 |
|
22 |
|
23 | PromotedState[PromotedState["NotPromoted"] = 0] = "NotPromoted";
|
24 | |
25 |
|
26 |
|
27 | PromotedState[PromotedState["PromoteOnPublish"] = 1] = "PromoteOnPublish";
|
28 | |
29 |
|
30 |
|
31 | PromotedState[PromotedState["Promoted"] = 2] = "Promoted";
|
32 | })(PromotedState || (PromotedState = {}));
|
33 |
|
34 |
|
35 |
|
36 | export class _ClientsidePage extends _SPQueryable {
|
37 | |
38 |
|
39 |
|
40 | constructor(base, path, json, noInit = false, sections = [], commentsDisabled = false) {
|
41 | super(base, path);
|
42 | this.json = json;
|
43 | this.sections = sections;
|
44 | this.commentsDisabled = commentsDisabled;
|
45 | this._bannerImageDirty = false;
|
46 | this._bannerImageThumbnailUrlDirty = false;
|
47 | this.parentUrl = "";
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | this._url = combine(extractWebUrl(this._url), path);
|
53 |
|
54 | this._pageSettings = { controlType: 0, pageSettingsSlice: { isDefaultDescription: true, isDefaultThumbnail: true } };
|
55 |
|
56 | this._layoutPart = _ClientsidePage.getDefaultLayoutPart();
|
57 | if (typeof json !== "undefined" && !noInit) {
|
58 | this.fromJSON(json);
|
59 | }
|
60 | }
|
61 | static getDefaultLayoutPart() {
|
62 | return {
|
63 | dataVersion: "1.4",
|
64 | description: "Title Region Description",
|
65 | id: "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
|
66 | instanceId: "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
|
67 | properties: {
|
68 | authorByline: [],
|
69 | authors: [],
|
70 | layoutType: "FullWidthImage",
|
71 | showPublishDate: false,
|
72 | showTopicHeader: false,
|
73 | textAlignment: "Left",
|
74 | title: "",
|
75 | topicHeader: "",
|
76 | enableGradientEffect: true,
|
77 | },
|
78 | reservedHeight: 280,
|
79 | serverProcessedContent: { htmlStrings: {}, searchablePlainTexts: {}, imageSources: {}, links: {} },
|
80 | title: "Title area",
|
81 | };
|
82 | }
|
83 | get pageLayout() {
|
84 | return this.json.PageLayoutType;
|
85 | }
|
86 | set pageLayout(value) {
|
87 | this.json.PageLayoutType = value;
|
88 | }
|
89 | get bannerImageUrl() {
|
90 | return this.json.BannerImageUrl;
|
91 | }
|
92 | set bannerImageUrl(value) {
|
93 | this.setBannerImage(value);
|
94 | }
|
95 | get thumbnailUrl() {
|
96 | return this._pageSettings.pageSettingsSlice.isDefaultThumbnail ? this.json.BannerImageUrl : this.json.BannerThumbnailUrl;
|
97 | }
|
98 | set thumbnailUrl(value) {
|
99 | this.json.BannerThumbnailUrl = value;
|
100 | this._bannerImageThumbnailUrlDirty = true;
|
101 | this._pageSettings.pageSettingsSlice.isDefaultThumbnail = false;
|
102 | }
|
103 | get topicHeader() {
|
104 | return objectDefinedNotNull(this.json.TopicHeader) ? this.json.TopicHeader : "";
|
105 | }
|
106 | set topicHeader(value) {
|
107 | this.json.TopicHeader = value;
|
108 | this._layoutPart.properties.topicHeader = value;
|
109 | if (stringIsNullOrEmpty(value)) {
|
110 | this.showTopicHeader = false;
|
111 | }
|
112 | }
|
113 | get title() {
|
114 | return this.json.Title;
|
115 | }
|
116 | set title(value) {
|
117 | this.json.Title = value;
|
118 | this._layoutPart.properties.title = value;
|
119 | }
|
120 | get reservedHeight() {
|
121 | return this._layoutPart.reservedHeight;
|
122 | }
|
123 | set reservedHeight(value) {
|
124 | this._layoutPart.reservedHeight = value;
|
125 | }
|
126 | get description() {
|
127 | return this.json.Description;
|
128 | }
|
129 | set description(value) {
|
130 | if (!stringIsNullOrEmpty(value) && value.length > 255) {
|
131 | throw Error("Modern Page description is limited to 255 chars.");
|
132 | }
|
133 | this.json.Description = value;
|
134 | if (!hOP(this._pageSettings, "htmlAttributes")) {
|
135 | this._pageSettings.htmlAttributes = [];
|
136 | }
|
137 | if (this._pageSettings.htmlAttributes.indexOf("modifiedDescription") < 0) {
|
138 | this._pageSettings.htmlAttributes.push("modifiedDescription");
|
139 | }
|
140 | this._pageSettings.pageSettingsSlice.isDefaultDescription = false;
|
141 | }
|
142 | get layoutType() {
|
143 | return this._layoutPart.properties.layoutType;
|
144 | }
|
145 | set layoutType(value) {
|
146 | this._layoutPart.properties.layoutType = value;
|
147 | }
|
148 | get headerTextAlignment() {
|
149 | return this._layoutPart.properties.textAlignment;
|
150 | }
|
151 | set headerTextAlignment(value) {
|
152 | this._layoutPart.properties.textAlignment = value;
|
153 | }
|
154 | get showTopicHeader() {
|
155 | return this._layoutPart.properties.showTopicHeader;
|
156 | }
|
157 | set showTopicHeader(value) {
|
158 | this._layoutPart.properties.showTopicHeader = value;
|
159 | }
|
160 | get showPublishDate() {
|
161 | return this._layoutPart.properties.showPublishDate;
|
162 | }
|
163 | set showPublishDate(value) {
|
164 | this._layoutPart.properties.showPublishDate = value;
|
165 | }
|
166 | get hasVerticalSection() {
|
167 | return this.sections.findIndex(s => s.layoutIndex === 2) > -1;
|
168 | }
|
169 | get authorByLine() {
|
170 | if (isArray(this._layoutPart.properties.authorByline) && this._layoutPart.properties.authorByline.length > 0) {
|
171 | return this._layoutPart.properties.authorByline[0];
|
172 | }
|
173 | return null;
|
174 | }
|
175 | get verticalSection() {
|
176 | if (this.hasVerticalSection) {
|
177 | return this.addVerticalSection();
|
178 | }
|
179 | return null;
|
180 | }
|
181 | |
182 |
|
183 |
|
184 | addSection() {
|
185 | const section = new CanvasSection(this, getNextOrder(this.sections), 1);
|
186 | this.sections.push(section);
|
187 | return section;
|
188 | }
|
189 | |
190 |
|
191 |
|
192 | addVerticalSection() {
|
193 |
|
194 | const sectionIndex = this.sections.findIndex(s => s.layoutIndex === 2);
|
195 | if (sectionIndex > -1) {
|
196 | return this.sections[sectionIndex];
|
197 | }
|
198 | const section = new CanvasSection(this, getNextOrder(this.sections), 2);
|
199 | this.sections.push(section);
|
200 | return section;
|
201 | }
|
202 | |
203 |
|
204 |
|
205 |
|
206 |
|
207 | fromJSON(pageData) {
|
208 | this.json = pageData;
|
209 | const canvasControls = JSON.parse(pageData.CanvasContent1);
|
210 | const layouts = JSON.parse(pageData.LayoutWebpartsContent);
|
211 | if (layouts && layouts.length > 0) {
|
212 | this._layoutPart = layouts[0];
|
213 | }
|
214 | this.setControls(canvasControls);
|
215 | return this;
|
216 | }
|
217 | |
218 |
|
219 |
|
220 | async load() {
|
221 | const item = await this.getItem("Id", "CommentsDisabled");
|
222 | const pageData = await SPQueryable(this, `_api/sitepages/pages(${item.Id})`)();
|
223 | this.commentsDisabled = item.CommentsDisabled;
|
224 | return this.fromJSON(pageData);
|
225 | }
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 | async save(publish = true) {
|
232 | if (this.json.Id === null) {
|
233 | throw Error("The id for this page is null. If you want to create a new page, please use ClientSidePage.Create");
|
234 | }
|
235 | const previewPartialUrl = "_layouts/15/getpreview.ashx";
|
236 |
|
237 | if (this._bannerImageDirty && !this.bannerImageUrl.includes(previewPartialUrl)) {
|
238 | const serverRelativePath = this.bannerImageUrl;
|
239 | let imgInfo;
|
240 | let webUrl;
|
241 | const web = Web(this);
|
242 | const [batch, execute] = createBatch(web);
|
243 | web.using(batch);
|
244 | web.getFileByServerRelativePath(serverRelativePath.replace(/%20/ig, " "))
|
245 | .select("ListId", "WebId", "UniqueId", "Name", "SiteId")().then(r1 => imgInfo = r1);
|
246 | web.select("Url")().then(r2 => webUrl = r2.Url);
|
247 |
|
248 | await execute();
|
249 | const f = SPQueryable(webUrl, previewPartialUrl);
|
250 | f.query.set("guidSite", `${imgInfo.SiteId}`);
|
251 | f.query.set("guidWeb", `${imgInfo.WebId}`);
|
252 | f.query.set("guidFile", `${imgInfo.UniqueId}`);
|
253 | this.bannerImageUrl = f.toRequestUrl();
|
254 | if (!objectDefinedNotNull(this._layoutPart.serverProcessedContent)) {
|
255 | this._layoutPart.serverProcessedContent = {};
|
256 | }
|
257 | this._layoutPart.serverProcessedContent.imageSources = { imageSource: serverRelativePath };
|
258 | if (!objectDefinedNotNull(this._layoutPart.serverProcessedContent.customMetadata)) {
|
259 | this._layoutPart.serverProcessedContent.customMetadata = {};
|
260 | }
|
261 | this._layoutPart.serverProcessedContent.customMetadata.imageSource = {
|
262 | listId: imgInfo.ListId,
|
263 | siteId: imgInfo.SiteId,
|
264 | uniqueId: imgInfo.UniqueId,
|
265 | webId: imgInfo.WebId,
|
266 | };
|
267 | this._layoutPart.properties.webId = imgInfo.WebId;
|
268 | this._layoutPart.properties.siteId = imgInfo.SiteId;
|
269 | this._layoutPart.properties.listId = imgInfo.ListId;
|
270 | this._layoutPart.properties.uniqueId = imgInfo.UniqueId;
|
271 | }
|
272 |
|
273 | if (!this.json.IsPageCheckedOutToCurrentUser) {
|
274 | await spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/checkoutpage`));
|
275 | }
|
276 |
|
277 | let saveBody = {
|
278 | AuthorByline: this.json.AuthorByline || [],
|
279 | CanvasContent1: this.getCanvasContent1(),
|
280 | Description: this.description,
|
281 | LayoutWebpartsContent: this.getLayoutWebpartsContent(),
|
282 | Title: this.title,
|
283 | TopicHeader: this.topicHeader,
|
284 | BannerImageUrl: this.bannerImageUrl,
|
285 | };
|
286 | if (this._bannerImageDirty || this._bannerImageThumbnailUrlDirty) {
|
287 | const bannerImageUrlValue = this._bannerImageThumbnailUrlDirty ? this.thumbnailUrl : this.bannerImageUrl;
|
288 | saveBody = {
|
289 | BannerImageUrl: bannerImageUrlValue,
|
290 | ...saveBody,
|
291 | };
|
292 | }
|
293 | const updater = ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/savepage`);
|
294 | await spPost(updater, headers({ "if-match": "*" }, body(saveBody)));
|
295 | let r = true;
|
296 | if (publish) {
|
297 | r = await spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/publish`));
|
298 | if (r) {
|
299 | this.json.IsPageCheckedOutToCurrentUser = false;
|
300 | }
|
301 | }
|
302 | this._bannerImageDirty = false;
|
303 | this._bannerImageThumbnailUrlDirty = false;
|
304 |
|
305 | await this.load();
|
306 | return r;
|
307 | }
|
308 | |
309 |
|
310 |
|
311 | async discardPageCheckout() {
|
312 | if (this.json.Id === null) {
|
313 | throw Error("The id for this page is null. If you want to create a new page, please use ClientSidePage.Create");
|
314 | }
|
315 | const d = await spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/discardPage`));
|
316 | this.fromJSON(d);
|
317 | }
|
318 | |
319 |
|
320 |
|
321 | async promoteToNews() {
|
322 | return this.promoteNewsImpl("promoteToNews");
|
323 | }
|
324 |
|
325 |
|
326 |
|
327 |
|
328 | |
329 |
|
330 |
|
331 |
|
332 |
|
333 | findControlById(id) {
|
334 | return this.findControl((c) => c.id === id);
|
335 | }
|
336 | |
337 |
|
338 |
|
339 |
|
340 |
|
341 | findControl(predicate) {
|
342 |
|
343 | for (let i = 0; i < this.sections.length; i++) {
|
344 |
|
345 | for (let j = 0; j < this.sections[i].columns.length; j++) {
|
346 |
|
347 | for (let k = 0; k < this.sections[i].columns[j].controls.length; k++) {
|
348 |
|
349 | if (predicate(this.sections[i].columns[j].controls[k])) {
|
350 | return this.sections[i].columns[j].controls[k];
|
351 | }
|
352 | }
|
353 | }
|
354 | }
|
355 |
|
356 | return null;
|
357 | }
|
358 | |
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 | async copy(web, pageName, title, publish = true, promotedState) {
|
367 | const page = await CreateClientsidePage(web, pageName, title, this.pageLayout, promotedState);
|
368 | return this.copyTo(page, publish);
|
369 | }
|
370 | |
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 | async copyTo(page, publish = true) {
|
377 |
|
378 | page.setControls(this.getControls());
|
379 |
|
380 | if (this._layoutPart.properties) {
|
381 | if (hOP(this._layoutPart.properties, "topicHeader")) {
|
382 | page.topicHeader = this._layoutPart.properties.topicHeader;
|
383 | }
|
384 | if (hOP(this._layoutPart.properties, "imageSourceType")) {
|
385 | page._layoutPart.properties.imageSourceType = this._layoutPart.properties.imageSourceType;
|
386 | }
|
387 | if (hOP(this._layoutPart.properties, "layoutType")) {
|
388 | page._layoutPart.properties.layoutType = this._layoutPart.properties.layoutType;
|
389 | }
|
390 | if (hOP(this._layoutPart.properties, "textAlignment")) {
|
391 | page._layoutPart.properties.textAlignment = this._layoutPart.properties.textAlignment;
|
392 | }
|
393 | if (hOP(this._layoutPart.properties, "showTopicHeader")) {
|
394 | page._layoutPart.properties.showTopicHeader = this._layoutPart.properties.showTopicHeader;
|
395 | }
|
396 | if (hOP(this._layoutPart.properties, "showPublishDate")) {
|
397 | page._layoutPart.properties.showPublishDate = this._layoutPart.properties.showPublishDate;
|
398 | }
|
399 | if (hOP(this._layoutPart.properties, "enableGradientEffect")) {
|
400 | page._layoutPart.properties.enableGradientEffect = this._layoutPart.properties.enableGradientEffect;
|
401 | }
|
402 | }
|
403 |
|
404 | if (!stringIsNullOrEmpty(this.json.BannerImageUrl)) {
|
405 |
|
406 | const url = new URL(this.json.BannerImageUrl);
|
407 |
|
408 | const makeGuid = (s) => s.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/g, "$1-$2-$3-$4-$5");
|
409 |
|
410 | if (url.searchParams.has("guidSite") && url.searchParams.has("guidWeb") && url.searchParams.has("guidFile")) {
|
411 | const guidSite = makeGuid(url.searchParams.get("guidSite"));
|
412 | const guidWeb = makeGuid(url.searchParams.get("guidWeb"));
|
413 | const guidFile = makeGuid(url.searchParams.get("guidFile"));
|
414 | const site = Site(this);
|
415 | const id = await site.select("Id")();
|
416 |
|
417 | if (id.Id === guidSite) {
|
418 | const openWeb = await site.openWebById(guidWeb);
|
419 | const file = await openWeb.web.getFileById(guidFile).select("ServerRelativeUrl")();
|
420 | const props = {};
|
421 | if (this._layoutPart.properties) {
|
422 | if (hOP(this._layoutPart.properties, "translateX")) {
|
423 | props.translateX = this._layoutPart.properties.translateX;
|
424 | }
|
425 | if (hOP(this._layoutPart.properties, "translateY")) {
|
426 | props.translateY = this._layoutPart.properties.translateY;
|
427 | }
|
428 | if (hOP(this._layoutPart.properties, "imageSourceType")) {
|
429 | props.imageSourceType = this._layoutPart.properties.imageSourceType;
|
430 | }
|
431 | if (hOP(this._layoutPart.properties, "altText")) {
|
432 | props.altText = this._layoutPart.properties.altText;
|
433 | }
|
434 | }
|
435 | page.setBannerImage(file.ServerRelativeUrl, props);
|
436 | }
|
437 | }
|
438 | }
|
439 | await page.save(publish);
|
440 | return page;
|
441 | }
|
442 | |
443 |
|
444 |
|
445 |
|
446 |
|
447 |
|
448 |
|
449 | setBannerImage(url, props) {
|
450 | if (isUrlAbsolute(url)) {
|
451 |
|
452 | url = url.replace(/^https?:\/\/[a-z0-9.]*?\.[a-z]{2,3}\//i, "/");
|
453 | }
|
454 | this.json.BannerImageUrl = url;
|
455 |
|
456 | this._layoutPart.serverProcessedContent = { imageSources: { imageSource: url } };
|
457 | this._bannerImageDirty = true;
|
458 | |
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 | if (!this._bannerImageThumbnailUrlDirty) {
|
465 | this.thumbnailUrl = url;
|
466 | this._pageSettings.pageSettingsSlice.isDefaultThumbnail = true;
|
467 | }
|
468 |
|
469 | this._layoutPart.properties.imageSourceType = 2;
|
470 | if (objectDefinedNotNull(props)) {
|
471 | if (hOP(props, "translateX")) {
|
472 | this._layoutPart.properties.translateX = props.translateX;
|
473 | }
|
474 | if (hOP(props, "translateY")) {
|
475 | this._layoutPart.properties.translateY = props.translateY;
|
476 | }
|
477 | if (hOP(props, "imageSourceType")) {
|
478 | this._layoutPart.properties.imageSourceType = props.imageSourceType;
|
479 | }
|
480 | if (hOP(props, "altText")) {
|
481 | this._layoutPart.properties.altText = props.altText;
|
482 | }
|
483 | }
|
484 | }
|
485 | |
486 |
|
487 |
|
488 |
|
489 |
|
490 |
|
491 | async setBannerImageFromExternalUrl(url, props) {
|
492 |
|
493 | const fileUrl = new URL(url);
|
494 |
|
495 | const pageName = this.json.FileName.replace(/\.[^/.]+$/, "");
|
496 |
|
497 | const filename = fileUrl.pathname.split(/[\\/]/i).pop();
|
498 | const request = ClientsidePage(this, "_api/sitepages/AddImageFromExternalUrl");
|
499 | request.query.set("imageFileName", `'${filename}'`);
|
500 | request.query.set("pageName", `'${pageName}'`);
|
501 | request.query.set("externalUrl", `'${url}'`);
|
502 | request.select("ServerRelativeUrl");
|
503 | const result = await spPost(request);
|
504 |
|
505 | this.setBannerImage(result.ServerRelativeUrl, props);
|
506 | }
|
507 | |
508 |
|
509 |
|
510 |
|
511 |
|
512 | async setAuthorById(authorId) {
|
513 | const userLoginData = await SPCollection([this, extractWebUrl(this.toUrl())], "/_api/web/siteusers")
|
514 | .filter(`Id eq ${authorId}`)
|
515 | .select("LoginName")();
|
516 | if (userLoginData.length < 1) {
|
517 | throw Error(`Could not find user with id ${authorId}.`);
|
518 | }
|
519 | return this.setAuthorByLoginName(userLoginData[0].LoginName);
|
520 | }
|
521 | |
522 |
|
523 |
|
524 |
|
525 |
|
526 | async setAuthorByLoginName(authorLoginName) {
|
527 | const userLoginData = await SPCollection([this, extractWebUrl(this.toUrl())], "/_api/web/siteusers")
|
528 | .filter(`LoginName eq '${authorLoginName}'`)
|
529 | .select("UserPrincipalName", "Title")();
|
530 | if (userLoginData.length < 1) {
|
531 | throw Error(`Could not find user with login name '${authorLoginName}'.`);
|
532 | }
|
533 | this.json.AuthorByline = [userLoginData[0].UserPrincipalName];
|
534 | this._layoutPart.properties.authorByline = [userLoginData[0].UserPrincipalName];
|
535 | this._layoutPart.properties.authors = [{
|
536 | id: authorLoginName,
|
537 | name: userLoginData[0].Title,
|
538 | role: "",
|
539 | upn: userLoginData[0].UserPrincipalName,
|
540 | }];
|
541 | }
|
542 | |
543 |
|
544 |
|
545 |
|
546 |
|
547 | async getItem(...selects) {
|
548 | const initer = ClientsidePage(this, "/_api/lists/EnsureClientRenderedSitePagesLibrary").select("EnableModeration", "EnableMinorVersions", "Id");
|
549 | const listData = await spPost(initer);
|
550 | const item = List([this, listData["odata.id"]]).items.getById(this.json.Id);
|
551 | const itemData = await item.select(...selects)();
|
552 | return Object.assign(Item([this, odataUrlFrom(itemData)]), itemData);
|
553 | }
|
554 | |
555 |
|
556 |
|
557 | async recycle() {
|
558 | const item = await this.getItem();
|
559 | await item.recycle();
|
560 | }
|
561 | |
562 |
|
563 |
|
564 | async delete() {
|
565 | const item = await this.getItem();
|
566 | await item.delete();
|
567 | }
|
568 | |
569 |
|
570 |
|
571 |
|
572 |
|
573 |
|
574 | async schedulePublish(publishDate) {
|
575 | return spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/SchedulePublish`), body({
|
576 | sitePage: { PublishStartDate: publishDate },
|
577 | }));
|
578 | }
|
579 | |
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 | async saveAsTemplate(publish = true) {
|
586 | const data = await spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/SavePageAsTemplate`));
|
587 | const page = ClientsidePage(this, null, data);
|
588 | page.title = this.title;
|
589 | await page.save(publish);
|
590 | return page;
|
591 | }
|
592 | |
593 |
|
594 |
|
595 |
|
596 |
|
597 |
|
598 |
|
599 | share(emails, message) {
|
600 | return spPost(ClientsidePage(this, "_api/SP.Publishing.RichSharing/SharePageByEmail"), body({
|
601 | recipientEmails: emails,
|
602 | message,
|
603 | url: this.json.AbsoluteUrl,
|
604 | }));
|
605 | }
|
606 | getCanvasContent1() {
|
607 | return JSON.stringify(this.getControls());
|
608 | }
|
609 | getLayoutWebpartsContent() {
|
610 | if (this._layoutPart) {
|
611 | return JSON.stringify([this._layoutPart]);
|
612 | }
|
613 | else {
|
614 | return JSON.stringify(null);
|
615 | }
|
616 | }
|
617 | setControls(controls) {
|
618 |
|
619 | this.sections = [];
|
620 | if (controls && controls.length) {
|
621 | for (let i = 0; i < controls.length; i++) {
|
622 |
|
623 | const controlType = hOP(controls[i], "controlType") ? controls[i].controlType : 0;
|
624 | switch (controlType) {
|
625 | case 0:
|
626 |
|
627 | if (hOP(controls[i], "pageSettingsSlice")) {
|
628 | this._pageSettings = controls[i];
|
629 | }
|
630 | else {
|
631 |
|
632 | this.mergeColumnToTree(new CanvasColumn(controls[i]));
|
633 | }
|
634 | break;
|
635 | case 3: {
|
636 | const part = new ClientsideWebpart(controls[i]);
|
637 | this.mergePartToTree(part, part.data.position);
|
638 | break;
|
639 | }
|
640 | case 4: {
|
641 | const textData = controls[i];
|
642 | const text = new ClientsideText(textData.innerHTML, textData);
|
643 | this.mergePartToTree(text, text.data.position);
|
644 | break;
|
645 | }
|
646 | }
|
647 | }
|
648 | reindex(this.sections);
|
649 | }
|
650 | }
|
651 | getControls() {
|
652 |
|
653 | reindex(this.sections);
|
654 |
|
655 | const canvasData = [];
|
656 | this.sections.forEach(section => {
|
657 | section.columns.forEach(column => {
|
658 | if (column.controls.length < 1) {
|
659 |
|
660 | canvasData.push({
|
661 | displayMode: column.data.displayMode,
|
662 | emphasis: this.getEmphasisObj(section.emphasis),
|
663 | position: column.data.position,
|
664 | });
|
665 | }
|
666 | else {
|
667 | column.controls.forEach(control => {
|
668 | control.data.emphasis = this.getEmphasisObj(section.emphasis);
|
669 | canvasData.push(this.specialSaveHandling(control).data);
|
670 | });
|
671 | }
|
672 | });
|
673 | });
|
674 | canvasData.push(this._pageSettings);
|
675 | return canvasData;
|
676 | }
|
677 | getEmphasisObj(value) {
|
678 | if (value < 1 || value > 3) {
|
679 | return {};
|
680 | }
|
681 | return { zoneEmphasis: value };
|
682 | }
|
683 | async promoteNewsImpl(method) {
|
684 | if (this.json.Id === null) {
|
685 | throw Error("The id for this page is null.");
|
686 | }
|
687 |
|
688 |
|
689 |
|
690 | if (stringIsNullOrEmpty(this.json.VersionInfo.LastVersionCreatedBy)) {
|
691 | const lastPubData = new Date(this.json.VersionInfo.LastVersionCreated);
|
692 |
|
693 | if (lastPubData.getFullYear() < 2000) {
|
694 | await this.save(true);
|
695 | }
|
696 | }
|
697 | return spPost(ClientsidePage(this, `_api/sitepages/pages(${this.json.Id})/${method}`));
|
698 | }
|
699 | |
700 |
|
701 |
|
702 |
|
703 |
|
704 | mergePartToTree(control, positionData) {
|
705 | var _a, _b, _c;
|
706 | let column = null;
|
707 | let sectionFactor = 12;
|
708 | let sectionIndex = 0;
|
709 | let zoneIndex = 0;
|
710 | let layoutIndex = 1;
|
711 |
|
712 | if (positionData) {
|
713 | if (hOP(positionData, "zoneIndex")) {
|
714 | zoneIndex = positionData.zoneIndex;
|
715 | }
|
716 | if (hOP(positionData, "sectionIndex")) {
|
717 | sectionIndex = positionData.sectionIndex;
|
718 | }
|
719 | if (hOP(positionData, "sectionFactor")) {
|
720 | sectionFactor = positionData.sectionFactor;
|
721 | }
|
722 | if (hOP(positionData, "layoutIndex")) {
|
723 | layoutIndex = positionData.layoutIndex;
|
724 | }
|
725 | }
|
726 | const zoneEmphasis = (_c = (_b = (_a = control.data) === null || _a === void 0 ? void 0 : _a.emphasis) === null || _b === void 0 ? void 0 : _b.zoneEmphasis) !== null && _c !== void 0 ? _c : 0;
|
727 | const section = this.getOrCreateSection(zoneIndex, layoutIndex, zoneEmphasis);
|
728 | const columns = section.columns.filter(c => c.order === sectionIndex);
|
729 | if (columns.length < 1) {
|
730 | column = section.addColumn(sectionFactor, layoutIndex);
|
731 | }
|
732 | else {
|
733 | column = columns[0];
|
734 | }
|
735 | control.column = column;
|
736 | column.addControl(control);
|
737 | }
|
738 | |
739 |
|
740 |
|
741 |
|
742 |
|
743 |
|
744 | mergeColumnToTree(column) {
|
745 | var _a, _b;
|
746 | const order = hOP(column.data, "position") && hOP(column.data.position, "zoneIndex") ? column.data.position.zoneIndex : 0;
|
747 | const layoutIndex = hOP(column.data, "position") && hOP(column.data.position, "layoutIndex") ? column.data.position.layoutIndex : 1;
|
748 | const section = this.getOrCreateSection(order, layoutIndex, ((_b = (_a = column.data) === null || _a === void 0 ? void 0 : _a.emphasis) === null || _b === void 0 ? void 0 : _b.zoneEmphasis) || 0);
|
749 | column.section = section;
|
750 | section.columns.push(column);
|
751 | }
|
752 | |
753 |
|
754 |
|
755 |
|
756 |
|
757 |
|
758 |
|
759 | getOrCreateSection(order, layoutIndex, emphasis) {
|
760 | let section = null;
|
761 | const sections = this.sections.filter(s => s.order === order && s.layoutIndex === layoutIndex);
|
762 | if (sections.length < 1) {
|
763 | section = layoutIndex === 2 ? this.addVerticalSection() : this.addSection();
|
764 | section.order = order;
|
765 | section.emphasis = emphasis;
|
766 | }
|
767 | else {
|
768 | section = sections[0];
|
769 | }
|
770 | return section;
|
771 | }
|
772 | |
773 |
|
774 |
|
775 |
|
776 |
|
777 |
|
778 | specialSaveHandling(control) {
|
779 | var _a, _b, _c;
|
780 |
|
781 |
|
782 |
|
783 | if (control.data.controlType === 3) {
|
784 | const texts = ((_c = (_b = (_a = control.data) === null || _a === void 0 ? void 0 : _a.webPartData) === null || _b === void 0 ? void 0 : _b.serverProcessedContent) === null || _c === void 0 ? void 0 : _c.searchablePlainTexts) || null;
|
785 | if (objectDefinedNotNull(texts)) {
|
786 | const keys = Object.getOwnPropertyNames(texts);
|
787 | for (let i = 0; i < keys.length; i++) {
|
788 | texts[keys[i]] = texts[keys[i]].replace(/</ig, "<");
|
789 | control.data.webPartData.serverProcessedContent.searchablePlainTexts = texts;
|
790 | }
|
791 | }
|
792 | }
|
793 | return control;
|
794 | }
|
795 | }
|
796 |
|
797 |
|
798 |
|
799 | const ClientsidePage = (base, path, json, noInit = false, sections = [], commentsDisabled = false) => {
|
800 | return new _ClientsidePage(base, path, json, noInit, sections, commentsDisabled);
|
801 | };
|
802 |
|
803 |
|
804 |
|
805 |
|
806 |
|
807 | export const ClientsidePageFromFile = async (file) => {
|
808 | const item = await file.getItem();
|
809 | const page = ClientsidePage([file, extractWebUrl(file.toUrl())], "", { Id: item.Id }, true);
|
810 | return page.load();
|
811 | };
|
812 |
|
813 |
|
814 |
|
815 |
|
816 |
|
817 |
|
818 |
|
819 |
|
820 | export const CreateClientsidePage = async (web, pageName, title, PageLayoutType = "Article", promotedState = 0) => {
|
821 |
|
822 |
|
823 | pageName = pageName.replace(/\.aspx$/i, "");
|
824 |
|
825 | const pageInitData = await spPost(ClientsidePage(web, "_api/sitepages/pages"), body({
|
826 | PageLayoutType,
|
827 | PromotedState: promotedState,
|
828 | }));
|
829 |
|
830 | const newPage = ClientsidePage(web, "", pageInitData);
|
831 | newPage.title = pageName;
|
832 | await newPage.save(false);
|
833 | newPage.title = title;
|
834 | return newPage;
|
835 | };
|
836 | export class CanvasSection {
|
837 | constructor(page, order, layoutIndex, columns = [], _emphasis = 0) {
|
838 | this.page = page;
|
839 | this.columns = columns;
|
840 | this._emphasis = _emphasis;
|
841 | this._memId = getGUID();
|
842 | this._order = order;
|
843 | this._layoutIndex = layoutIndex;
|
844 | }
|
845 | get order() {
|
846 | return this._order;
|
847 | }
|
848 | set order(value) {
|
849 | this._order = value;
|
850 | for (let i = 0; i < this.columns.length; i++) {
|
851 | this.columns[i].data.position.zoneIndex = value;
|
852 | }
|
853 | }
|
854 | get layoutIndex() {
|
855 | return this._layoutIndex;
|
856 | }
|
857 | set layoutIndex(value) {
|
858 | this._layoutIndex = value;
|
859 | for (let i = 0; i < this.columns.length; i++) {
|
860 | this.columns[i].data.position.layoutIndex = value;
|
861 | }
|
862 | }
|
863 | |
864 |
|
865 |
|
866 | get defaultColumn() {
|
867 | if (this.columns.length < 1) {
|
868 | this.addColumn(12);
|
869 | }
|
870 | return this.columns[0];
|
871 | }
|
872 | |
873 |
|
874 |
|
875 | addColumn(factor, layoutIndex = this.layoutIndex) {
|
876 | const column = new CanvasColumn();
|
877 | column.section = this;
|
878 | column.data.position.zoneIndex = this.order;
|
879 | column.data.position.layoutIndex = layoutIndex;
|
880 | column.data.position.sectionFactor = factor;
|
881 | column.order = getNextOrder(this.columns);
|
882 | this.columns.push(column);
|
883 | return column;
|
884 | }
|
885 | |
886 |
|
887 |
|
888 |
|
889 |
|
890 | addControl(control) {
|
891 | this.defaultColumn.addControl(control);
|
892 | return this;
|
893 | }
|
894 | get emphasis() {
|
895 | return this._emphasis;
|
896 | }
|
897 | set emphasis(value) {
|
898 | this._emphasis = value;
|
899 | }
|
900 | |
901 |
|
902 |
|
903 | remove() {
|
904 | this.page.sections = this.page.sections.filter(section => section._memId !== this._memId);
|
905 | reindex(this.page.sections);
|
906 | }
|
907 | }
|
908 | export class CanvasColumn {
|
909 | constructor(json = JSON.parse(JSON.stringify(CanvasColumn.Default)), controls = []) {
|
910 | this.json = json;
|
911 | this.controls = controls;
|
912 | this._section = null;
|
913 | this._memId = getGUID();
|
914 | }
|
915 | get data() {
|
916 | return this.json;
|
917 | }
|
918 | get section() {
|
919 | return this._section;
|
920 | }
|
921 | set section(section) {
|
922 | this._section = section;
|
923 | }
|
924 | get order() {
|
925 | return this.data.position.sectionIndex;
|
926 | }
|
927 | set order(value) {
|
928 | this.data.position.sectionIndex = value;
|
929 | for (let i = 0; i < this.controls.length; i++) {
|
930 | this.controls[i].data.position.zoneIndex = this.data.position.zoneIndex;
|
931 | this.controls[i].data.position.layoutIndex = this.data.position.layoutIndex;
|
932 | this.controls[i].data.position.sectionIndex = value;
|
933 | }
|
934 | }
|
935 | get factor() {
|
936 | return this.data.position.sectionFactor;
|
937 | }
|
938 | set factor(value) {
|
939 | this.data.position.sectionFactor = value;
|
940 | }
|
941 | addControl(control) {
|
942 | control.column = this;
|
943 | this.controls.push(control);
|
944 | return this;
|
945 | }
|
946 | getControl(index) {
|
947 | return this.controls[index];
|
948 | }
|
949 | remove() {
|
950 | this.section.columns = this.section.columns.filter(column => column._memId !== this._memId);
|
951 | reindex(this.section.columns);
|
952 | }
|
953 | }
|
954 | CanvasColumn.Default = {
|
955 | controlType: 0,
|
956 | displayMode: 2,
|
957 | emphasis: {},
|
958 | position: {
|
959 | layoutIndex: 1,
|
960 | sectionFactor: 12,
|
961 | sectionIndex: 1,
|
962 | zoneIndex: 1,
|
963 | },
|
964 | };
|
965 | export class ColumnControl {
|
966 | constructor(json) {
|
967 | this.json = json;
|
968 | }
|
969 | get id() {
|
970 | return this.json.id;
|
971 | }
|
972 | get data() {
|
973 | return this.json;
|
974 | }
|
975 | get column() {
|
976 | return this._column;
|
977 | }
|
978 | set column(value) {
|
979 | this._column = value;
|
980 | this.onColumnChange(this._column);
|
981 | }
|
982 | remove() {
|
983 | this.column.controls = this.column.controls.filter(control => control.id !== this.id);
|
984 | reindex(this.column.controls);
|
985 | }
|
986 | setData(data) {
|
987 | this.json = data;
|
988 | }
|
989 | }
|
990 | export class ClientsideText extends ColumnControl {
|
991 | constructor(text, json = JSON.parse(JSON.stringify(ClientsideText.Default))) {
|
992 | if (stringIsNullOrEmpty(json.id)) {
|
993 | json.id = getGUID();
|
994 | json.anchorComponentId = json.id;
|
995 | }
|
996 | super(json);
|
997 | this.text = text;
|
998 | }
|
999 | get text() {
|
1000 | return this.data.innerHTML;
|
1001 | }
|
1002 | set text(value) {
|
1003 | this.data.innerHTML = value;
|
1004 | }
|
1005 | get order() {
|
1006 | return this.data.position.controlIndex;
|
1007 | }
|
1008 | set order(value) {
|
1009 | this.data.position.controlIndex = value;
|
1010 | }
|
1011 | onColumnChange(col) {
|
1012 | this.data.position.sectionFactor = col.factor;
|
1013 | this.data.position.controlIndex = getNextOrder(col.controls);
|
1014 | this.data.position.zoneIndex = col.data.position.zoneIndex;
|
1015 | this.data.position.sectionIndex = col.order;
|
1016 | this.data.position.layoutIndex = col.data.position.layoutIndex;
|
1017 | }
|
1018 | }
|
1019 | ClientsideText.Default = {
|
1020 | addedFromPersistedData: false,
|
1021 | anchorComponentId: "",
|
1022 | controlType: 4,
|
1023 | displayMode: 2,
|
1024 | editorType: "CKEditor",
|
1025 | emphasis: {},
|
1026 | id: "",
|
1027 | innerHTML: "",
|
1028 | position: {
|
1029 | controlIndex: 1,
|
1030 | layoutIndex: 1,
|
1031 | sectionFactor: 12,
|
1032 | sectionIndex: 1,
|
1033 | zoneIndex: 1,
|
1034 | },
|
1035 | };
|
1036 | export class ClientsideWebpart extends ColumnControl {
|
1037 | constructor(json = JSON.parse(JSON.stringify(ClientsideWebpart.Default))) {
|
1038 | super(json);
|
1039 | }
|
1040 | static fromComponentDef(definition) {
|
1041 | const part = new ClientsideWebpart();
|
1042 | part.import(definition);
|
1043 | return part;
|
1044 | }
|
1045 | get title() {
|
1046 | return this.data.webPartData.title;
|
1047 | }
|
1048 | set title(value) {
|
1049 | this.data.webPartData.title = value;
|
1050 | }
|
1051 | get description() {
|
1052 | return this.data.webPartData.description;
|
1053 | }
|
1054 | set description(value) {
|
1055 | this.data.webPartData.description = value;
|
1056 | }
|
1057 | get order() {
|
1058 | return this.data.position.controlIndex;
|
1059 | }
|
1060 | set order(value) {
|
1061 | this.data.position.controlIndex = value;
|
1062 | }
|
1063 | get height() {
|
1064 | return this.data.reservedHeight;
|
1065 | }
|
1066 | set height(value) {
|
1067 | this.data.reservedHeight = value;
|
1068 | }
|
1069 | get width() {
|
1070 | return this.data.reservedWidth;
|
1071 | }
|
1072 | set width(value) {
|
1073 | this.data.reservedWidth = value;
|
1074 | }
|
1075 | get dataVersion() {
|
1076 | return this.data.webPartData.dataVersion;
|
1077 | }
|
1078 | set dataVersion(value) {
|
1079 | this.data.webPartData.dataVersion = value;
|
1080 | }
|
1081 | setProperties(properties) {
|
1082 | this.data.webPartData.properties = {
|
1083 | ...this.data.webPartData.properties,
|
1084 | ...properties,
|
1085 | };
|
1086 | return this;
|
1087 | }
|
1088 | getProperties() {
|
1089 | return this.data.webPartData.properties;
|
1090 | }
|
1091 | setServerProcessedContent(properties) {
|
1092 | this.data.webPartData.serverProcessedContent = {
|
1093 | ...this.data.webPartData.serverProcessedContent,
|
1094 | ...properties,
|
1095 | };
|
1096 | return this;
|
1097 | }
|
1098 | getServerProcessedContent() {
|
1099 | return this.data.webPartData.serverProcessedContent;
|
1100 | }
|
1101 | onColumnChange(col) {
|
1102 | this.data.position.sectionFactor = col.factor;
|
1103 | this.data.position.controlIndex = getNextOrder(col.controls);
|
1104 | this.data.position.zoneIndex = col.data.position.zoneIndex;
|
1105 | this.data.position.sectionIndex = col.data.position.sectionIndex;
|
1106 | this.data.position.layoutIndex = col.data.position.layoutIndex;
|
1107 | }
|
1108 | import(component) {
|
1109 | const id = getGUID();
|
1110 | const componendId = component.Id.replace(/^\{|\}$/g, "").toLowerCase();
|
1111 | const manifest = JSON.parse(component.Manifest);
|
1112 | const preconfiguredEntries = manifest.preconfiguredEntries[0];
|
1113 | this.setData(Object.assign({}, this.data, {
|
1114 | id,
|
1115 | webPartData: {
|
1116 | dataVersion: "1.0",
|
1117 | description: preconfiguredEntries.description.default,
|
1118 | id: componendId,
|
1119 | instanceId: id,
|
1120 | properties: preconfiguredEntries.properties,
|
1121 | title: preconfiguredEntries.title.default,
|
1122 | },
|
1123 | webPartId: componendId,
|
1124 | }));
|
1125 | }
|
1126 | }
|
1127 | ClientsideWebpart.Default = {
|
1128 | addedFromPersistedData: false,
|
1129 | controlType: 3,
|
1130 | displayMode: 2,
|
1131 | emphasis: {},
|
1132 | id: null,
|
1133 | position: {
|
1134 | controlIndex: 1,
|
1135 | layoutIndex: 1,
|
1136 | sectionFactor: 12,
|
1137 | sectionIndex: 1,
|
1138 | zoneIndex: 1,
|
1139 | },
|
1140 | reservedHeight: 500,
|
1141 | reservedWidth: 500,
|
1142 | webPartData: null,
|
1143 | webPartId: null,
|
1144 | };
|
1145 |
|
\ | No newline at end of file |