@ucd-lib/theme-elements 0.0.16 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +5 -1
- package/brand/ucd-theme-author-profile/ucd-theme-author-profile.js +222 -0
- package/brand/ucd-theme-author-profile/ucd-theme-author-profile.tpl.js +201 -0
- package/brand/ucd-theme-subnav/ucd-theme-subnav.js +0 -1
- package/package.json +4 -1
- package/ucdlib/ucdlib-md/ucdlib-md-content.js +31 -0
- package/ucdlib/ucdlib-md/ucdlib-md.js +120 -0
- package/ucdlib/ucdlib-sils-permalink/README.md +22 -0
- package/ucdlib/ucdlib-sils-permalink/ucdlib-sils-permalink-controller.js +36 -0
- package/ucdlib/ucdlib-sils-permalink/ucdlib-sils-permalink.js +324 -0
- package/ucdlib/ucdlib-sils-permalink/ucdlib-sils-permalink.tpl.js +337 -0
- package/utils/controllers/task.js +36 -0
package/.eslintrc.json
CHANGED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import {html, LitElement} from 'lit';
|
|
2
|
+
import {render, styles} from "./ucd-theme-author-profile.tpl.js";
|
|
3
|
+
import {TaskController} from '../../utils/controllers/task.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class AuthorProfile
|
|
7
|
+
* @description This author profile hydrates with the website wordpress api and goes into a profile block.
|
|
8
|
+
* @property {String} email - Email to reference person
|
|
9
|
+
* @property {String} domain - Specify the domain to choose from
|
|
10
|
+
*
|
|
11
|
+
* <ucdlib-author-profile domain="sandbox" email='sabaggett@ucdavis.edu></ucdlib-author-profile>
|
|
12
|
+
*/
|
|
13
|
+
export default class UcdlibAuthorProfile extends LitElement {
|
|
14
|
+
static get properties() {
|
|
15
|
+
return {
|
|
16
|
+
results : {type: Object, attribute:false},
|
|
17
|
+
email : {type: String},
|
|
18
|
+
id: {type: Number},
|
|
19
|
+
nameLast: {type: String},
|
|
20
|
+
nameFirst: {type: String},
|
|
21
|
+
link: {type: String},
|
|
22
|
+
contactWebsite: {type: String},
|
|
23
|
+
contactEmail: {type: String},
|
|
24
|
+
contactPhone: {type: String},
|
|
25
|
+
contactWebsiteLabel: {type: String},
|
|
26
|
+
contactEmailLabel: {type: String},
|
|
27
|
+
contactPhoneLabel: {type: String},
|
|
28
|
+
contactAppointmentUrl: {type: String},
|
|
29
|
+
positionTitle: {type: String},
|
|
30
|
+
photo: {type: Object},
|
|
31
|
+
department: {type: String},
|
|
32
|
+
domain: {type: String}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static get styles() {
|
|
37
|
+
return styles();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
this.PENDING = false;
|
|
43
|
+
this.LOADING = false;
|
|
44
|
+
this.COMPLETE = false;
|
|
45
|
+
this.ERROR = false;
|
|
46
|
+
this.results = {};
|
|
47
|
+
this.email = '';
|
|
48
|
+
this.domain = '';
|
|
49
|
+
this.errorMessage = 'This is not an email.';
|
|
50
|
+
|
|
51
|
+
this.svgIcon = {
|
|
52
|
+
'url': html`
|
|
53
|
+
<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
|
|
54
|
+
<path d="M640,328V312a16,16,0,0,0-16-16H344V256h72a32,32,0,0,0,32-32V96a32,32,0,0,0-32-32H224a32,32,0,0,0-32,32V224a32,32,0,0,0,32,32h72v40H16A16,16,0,0,0,0,312v16a16,16,0,0,0,16,16H120v40H64a32,32,0,0,0-32,32V544a32,32,0,0,0,32,32H224a32,32,0,0,0,32-32V416a32,32,0,0,0-32-32H168V344H472v40H416a32,32,0,0,0-32,32V544a32,32,0,0,0,32,32H576a32,32,0,0,0,32-32V416a32,32,0,0,0-32-32H520V344H624A16,16,0,0,0,640,328ZM256,192V128H384v64ZM192,512H96V448h96Zm352,0H448V448h96Z"/>
|
|
55
|
+
</svg> `,
|
|
56
|
+
'email': html`
|
|
57
|
+
<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
58
|
+
<path d="M502.3,190.8a6,6,0,0,1,9.7,4.7V400a48,48,0,0,1-48,48H48A48,48,0,0,1,0,400V195.6a6,6,0,0,1,9.7-4.7c22.4,17.4,52.1,39.5,154.1,113.6,21.1,15.4,56.7,47.8,92.2,47.6,35.7.3,72-32.8,92.3-47.6C450.3,230.4,479.9,208.2,502.3,190.8ZM256,320c23.2.4,56.6-29.2,73.4-41.4,132.7-96.3,142.8-104.7,173.4-128.7A23.93,23.93,0,0,0,512,131V112a48,48,0,0,0-48-48H48A48,48,0,0,0,0,112v19a24.08,24.08,0,0,0,9.2,18.9c30.6,23.9,40.7,32.4,173.4,128.7,16.8,12.2,50.2,41.8,73.4,41.4Z"/>
|
|
59
|
+
</svg>`,
|
|
60
|
+
'calendar': html `
|
|
61
|
+
<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg"viewBox="0 0 512 512">
|
|
62
|
+
<path d="M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z"/>
|
|
63
|
+
</svg>`,
|
|
64
|
+
'phone': html `
|
|
65
|
+
<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg"viewBox="0 0 512 512">
|
|
66
|
+
<path d="M497.39 361.8l-112-48a24 24 0 0 0-28 6.9l-49.6 60.6A370.66 370.66 0 0 1 130.6 204.11l60.6-49.6a23.94 23.94 0 0 0 6.9-28l-48-112A24.16 24.16 0 0 0 122.6.61l-104 24A24 24 0 0 0 0 48c0 256.5 207.9 464 464 464a24 24 0 0 0 23.4-18.6l24-104a24.29 24.29 0 0 0-14.01-27.6z"/>
|
|
67
|
+
</svg>
|
|
68
|
+
`
|
|
69
|
+
};
|
|
70
|
+
this.render=render.bind(this);
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @method firstUpdated
|
|
77
|
+
*
|
|
78
|
+
* @description updated when the page first renders
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} changedProperties
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
firstUpdated(){
|
|
84
|
+
if(this.email != ''){
|
|
85
|
+
this.eController = new TaskController(this, this._requestUrl());
|
|
86
|
+
|
|
87
|
+
this.requestUpdate();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @method validationLink
|
|
94
|
+
*
|
|
95
|
+
* @description Validates the email to make sure it is an email
|
|
96
|
+
*
|
|
97
|
+
* @param {String} email
|
|
98
|
+
*
|
|
99
|
+
* @returns {String}
|
|
100
|
+
*
|
|
101
|
+
*/
|
|
102
|
+
validationLink(email){
|
|
103
|
+
const regexExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/gi;
|
|
104
|
+
return regexExp.test(email);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @method validationLink
|
|
109
|
+
*
|
|
110
|
+
* @description Validates the email to make sure it is an email
|
|
111
|
+
*
|
|
112
|
+
* @param {String} email
|
|
113
|
+
*
|
|
114
|
+
* @returns {String}
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
_onPending(){
|
|
118
|
+
this.PENDING = true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @method _onError
|
|
123
|
+
*
|
|
124
|
+
* @description Sets error variable to true
|
|
125
|
+
*
|
|
126
|
+
* @param {String} e
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
_onError(e){
|
|
130
|
+
this.ERROR = true;
|
|
131
|
+
console.log(this.ERROR);
|
|
132
|
+
console.error(e);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @method _onComplete
|
|
137
|
+
*
|
|
138
|
+
* @description on complete defines the forms and updates
|
|
139
|
+
*
|
|
140
|
+
* @param {Object} results
|
|
141
|
+
*
|
|
142
|
+
*
|
|
143
|
+
*/
|
|
144
|
+
_onComplete(results){
|
|
145
|
+
this.results = results;
|
|
146
|
+
if(this.results.data != undefined) {
|
|
147
|
+
this.ERROR = true;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
this.COMPLETE = true;
|
|
151
|
+
this.PENDING = false;
|
|
152
|
+
this.LOADING = false;
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
this.id = this.results.id;
|
|
156
|
+
|
|
157
|
+
this.nameLast = this.results.nameLast;
|
|
158
|
+
|
|
159
|
+
this.nameFirst = this.results.nameFirst;
|
|
160
|
+
|
|
161
|
+
this.link = this.results.link;
|
|
162
|
+
|
|
163
|
+
this.contactWebsite = this.results.contactWebsite.length !== 0 ? this.results.contactWebsite[0].value :null;
|
|
164
|
+
|
|
165
|
+
this.contactEmail = this.results.contactEmail.length !== 0 ? this.results.contactEmail[0].value : null;
|
|
166
|
+
|
|
167
|
+
this.contactPhone = this.results.contactPhone.length !== 0 ? this.results.contactPhone[0].value : null;
|
|
168
|
+
|
|
169
|
+
this.contactAppointmentUrl = this.results.contactAppointmentUrl != "" ? this.results.contactAppointmentUrl : undefined;
|
|
170
|
+
|
|
171
|
+
this.positionTitle = this.results.positionTitle;
|
|
172
|
+
|
|
173
|
+
this.photo = Object.keys(this.results.photo).length !== 0 ? this.results.photo : "Empty";
|
|
174
|
+
|
|
175
|
+
this.department = this.results.department.title;
|
|
176
|
+
|
|
177
|
+
this.photoAlt = this.nameFirst + "_" + this.nameLast + "_Img";
|
|
178
|
+
|
|
179
|
+
this.requestUpdate();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @method _requestUrl
|
|
188
|
+
*
|
|
189
|
+
* @description configures the url and checks for email validation
|
|
190
|
+
*
|
|
191
|
+
* @returns {String}
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
_requestUrl(){
|
|
195
|
+
let email =this.email;
|
|
196
|
+
let validate = this.validationLink(email);
|
|
197
|
+
if(!validate) console.error(email);
|
|
198
|
+
let url;
|
|
199
|
+
|
|
200
|
+
url = "https://library.ucdavis.edu/wp-json/ucdlib-directory/person/" + String(email);
|
|
201
|
+
if (this.domain != "")
|
|
202
|
+
url = "https://" + this.domain + ".library.ucdavis.edu/wp-json/ucdlib-directory/person/" + String(email);
|
|
203
|
+
this.requestUpdate();
|
|
204
|
+
|
|
205
|
+
return url;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @method _onLoading
|
|
210
|
+
*
|
|
211
|
+
* @description Sets loading variable to true
|
|
212
|
+
*
|
|
213
|
+
*
|
|
214
|
+
*/
|
|
215
|
+
_onLoading(){
|
|
216
|
+
this.LOADING = true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
customElements.define('ucdlib-author-profile', UcdlibAuthorProfile);
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
import normalizeCss from "@ucd-lib/theme-sass/normalize.css.js";
|
|
4
|
+
import teaserStyles from "@ucd-lib/theme-sass/4_component/_index.css.js";
|
|
5
|
+
import baseStyles from "@ucd-lib/theme-sass/1_base_html/_index.css.js";
|
|
6
|
+
import buttons from "@ucd-lib/theme-sass/2_base_class/_index.css.js";
|
|
7
|
+
export function styles() {
|
|
8
|
+
const elementStyles = css`
|
|
9
|
+
:host {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
form {
|
|
13
|
+
width:100%;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
return [elementStyles,baseStyles,teaserStyles,normalizeCss, buttons];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function render() {
|
|
21
|
+
return html`
|
|
22
|
+
<style>
|
|
23
|
+
.vm-teaser__figure.category_loading{
|
|
24
|
+
background-color:#dcdcdc;
|
|
25
|
+
height:165px;
|
|
26
|
+
width:135px;
|
|
27
|
+
}
|
|
28
|
+
.load_teaser_a{
|
|
29
|
+
background-color:#dcdcdc;
|
|
30
|
+
width: 85%;
|
|
31
|
+
height:25px;
|
|
32
|
+
}
|
|
33
|
+
.load_teaser_b{
|
|
34
|
+
background-color:#dcdcdc;
|
|
35
|
+
width: 67%;
|
|
36
|
+
height:20px;
|
|
37
|
+
}
|
|
38
|
+
.load_teaser_c{
|
|
39
|
+
background-color:#dcdcdc;
|
|
40
|
+
width: 33.3%;
|
|
41
|
+
height:18px;
|
|
42
|
+
}
|
|
43
|
+
.container {
|
|
44
|
+
display: inline-grid;
|
|
45
|
+
grid-template-columns: 15% 85%;
|
|
46
|
+
width:100%;
|
|
47
|
+
}
|
|
48
|
+
.container-no-image {
|
|
49
|
+
display: inline-grid;
|
|
50
|
+
width:100%;
|
|
51
|
+
}
|
|
52
|
+
article {
|
|
53
|
+
margin-bottom: 50px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.photo {
|
|
57
|
+
position: relative;
|
|
58
|
+
width:90%;
|
|
59
|
+
height:90%;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.photo:after {
|
|
63
|
+
content: "";
|
|
64
|
+
display:inline-block;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.content {
|
|
68
|
+
position: absolute;
|
|
69
|
+
width: 70%;
|
|
70
|
+
height: 70%;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.text_container {
|
|
74
|
+
vertical-align:top;
|
|
75
|
+
display:inline-block;
|
|
76
|
+
}
|
|
77
|
+
.name {
|
|
78
|
+
color:var(--ucd-blue-80);
|
|
79
|
+
margin-bottom:0;
|
|
80
|
+
}
|
|
81
|
+
.title {
|
|
82
|
+
margin-bottom:0;
|
|
83
|
+
}
|
|
84
|
+
.info {
|
|
85
|
+
color:var(--ucd-blue-80);
|
|
86
|
+
margin-bottom:0;
|
|
87
|
+
}
|
|
88
|
+
.svg-icon {
|
|
89
|
+
width: 20px;
|
|
90
|
+
height: 20px;
|
|
91
|
+
fill: #73ABDD;
|
|
92
|
+
margin-right: 5px;
|
|
93
|
+
}
|
|
94
|
+
.contact-list{
|
|
95
|
+
display:inline-block;
|
|
96
|
+
margin-top:5px;
|
|
97
|
+
}
|
|
98
|
+
.pipe {
|
|
99
|
+
font-size:30px;
|
|
100
|
+
vertical-align: middle;
|
|
101
|
+
font-weight: lighter;
|
|
102
|
+
line-height: 25px;
|
|
103
|
+
color:#36454F;
|
|
104
|
+
}
|
|
105
|
+
.noApp-pipe {
|
|
106
|
+
display:none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@media (max-width: 800px) {
|
|
110
|
+
|
|
111
|
+
.contact-list {
|
|
112
|
+
display:block;
|
|
113
|
+
margin-bottom:5px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.contact-list .pipe {
|
|
117
|
+
display:none;
|
|
118
|
+
}
|
|
119
|
+
.photo {
|
|
120
|
+
width:90%;
|
|
121
|
+
height:90%;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@media (max-width: 550px) {
|
|
127
|
+
.container {
|
|
128
|
+
grid-template-columns: 35% 65%;
|
|
129
|
+
}
|
|
130
|
+
.photo {
|
|
131
|
+
width:80%;
|
|
132
|
+
height:80%;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
</style>
|
|
137
|
+
<!--
|
|
138
|
+
Starts the Permalink Fetch
|
|
139
|
+
-->
|
|
140
|
+
${this.eController ? html`
|
|
141
|
+
${this.eController.render({
|
|
142
|
+
complete: (result) => this._onComplete(result),
|
|
143
|
+
initial: () => this._onLoading(),
|
|
144
|
+
pending: () => this._onPending(),
|
|
145
|
+
error: (e) => this._onError(e)
|
|
146
|
+
})
|
|
147
|
+
}`:html``
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
<article>
|
|
151
|
+
${!this.LOADING ? html`
|
|
152
|
+
${this.photo != "Empty" && this.photo != undefined ?
|
|
153
|
+
html`
|
|
154
|
+
<div class="container">
|
|
155
|
+
<div class="photo"><img src="${this.photo.link}" alt="${this.photoAlt}"></div>
|
|
156
|
+
<div class="text_container">
|
|
157
|
+
<h3 class="name"><a class="name" href="">${this.nameFirst} ${this.nameLast}</a></h3>
|
|
158
|
+
<p class="title">${this.positionTitle} <span class="pipe">|</span> ${this.department}</p>
|
|
159
|
+
<p class="contact-list">${this.contactPhone ? html`${this.svgIcon.phone} <a class="info" href="tel:${this.contactPhone}">${this.contactPhone}</a> <span class="pipe">|</span>`: html``}</p>
|
|
160
|
+
<p class="contact-list">${this.contactEmail ? html`${this.svgIcon.email} <a class="info" href="mailto:${this.contactEmail}">${this.contactEmail}</a> ${this.contactAppointmentUrl ? html`<span class="pipe">|</span>`:html`<span class="noApp-pipe">|</span>`}`: html``}</p>
|
|
161
|
+
<p class="contact-list">${this.contactAppointmentUrl ? html`${this.svgIcon.calendar} <a class="info" href="${this.contactAppointmentUrl ? this.contactAppointmentUrl:"#"}">Book an Appointment</a>`: html``}</p>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
`
|
|
165
|
+
:html`
|
|
166
|
+
<div class="container-no-image">
|
|
167
|
+
<div class="text_container">
|
|
168
|
+
<h3 class="name"><a class="name" href="">${this.nameFirst} ${this.nameLast}</a></h3>
|
|
169
|
+
<p class="title">${this.positionTitle} <span class="pipe">|</span> ${this.department}</p>
|
|
170
|
+
<p class="contact-list">${this.contactPhone ? html`${this.svgIcon.phone} <a class="info" href="tel:${this.contactPhone}">${this.contactPhone}</a> <span class="pipe">|</span> `: html``}</p>
|
|
171
|
+
<p class="contact-list">${this.contactEmail ? html`${this.svgIcon.email} <a class="info" href="mailto:${this.contactEmail}">${this.contactEmail}</a> ${this.contactAppointmentUrl ? html`<span class="pipe">|</span>`:html`<span class="noApp-pipe">|</span>`}`: html``}</p>
|
|
172
|
+
<p class="contact-list">${this.contactAppointmentUrl ? html`${this.svgIcon.calendar} <a class="info" href="${this.contactAppointmentUrl ? this.contactAppointmentUrl:"#"}">Book an Appointment</a>`: html``}</p>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
`}
|
|
176
|
+
|
|
177
|
+
`:html`
|
|
178
|
+
${this.ERROR ? html`
|
|
179
|
+
<p>Person does not exist!</p>
|
|
180
|
+
`: html`
|
|
181
|
+
<!--
|
|
182
|
+
If it is in the loading stage of the permalink fetch
|
|
183
|
+
it will render this
|
|
184
|
+
look.
|
|
185
|
+
-->
|
|
186
|
+
<div class="vm-teaser__figure category_loading"></div>
|
|
187
|
+
<div class="vm-teaser__body">
|
|
188
|
+
<div class="load_teaser_a"></div>
|
|
189
|
+
<br/>
|
|
190
|
+
<div class="load_teaser_b"></div>
|
|
191
|
+
<br/>
|
|
192
|
+
<div class="load_teaser_c"></div>
|
|
193
|
+
<br/>
|
|
194
|
+
<div class="load_teaser_c"></div>
|
|
195
|
+
</div>
|
|
196
|
+
`}
|
|
197
|
+
|
|
198
|
+
`}
|
|
199
|
+
</article>
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
@@ -149,7 +149,6 @@ export default class UcdThemeSubnav extends Mixin(LitElement)
|
|
|
149
149
|
* @description Fires an 'item-click' event
|
|
150
150
|
* @param {Object} item - The link item
|
|
151
151
|
* @param {Array} location - The link location in links array
|
|
152
|
-
* @returns
|
|
153
152
|
*/
|
|
154
153
|
_dispatchItemClick(item, location){
|
|
155
154
|
if (item.href) return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ucd-lib/theme-elements",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Custom elements for the UCD brand theme",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,9 +9,12 @@
|
|
|
9
9
|
"author": "jrmerz@ucdavis.edu",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
+
"@lit-labs/task": "^1.0.0",
|
|
12
13
|
"@ucd-lib/theme-sass": "^5.0.15",
|
|
14
|
+
"dompurify": "^2.3.9",
|
|
13
15
|
"ip-cidr": "^3.0.4",
|
|
14
16
|
"lit": "^2.0.2",
|
|
17
|
+
"marked": "^4.0.18",
|
|
15
18
|
"photoswipe": "^4.1.3",
|
|
16
19
|
"slim-select": "^1.26.2"
|
|
17
20
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { MutationObserverController } from '../../utils/controllers';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @class UcdlibMdContent
|
|
6
|
+
* @classdesc Component class for declaritively wrapping markdown and translating into sanitized html
|
|
7
|
+
*/
|
|
8
|
+
export default class UcdlibMdContent extends LitElement {
|
|
9
|
+
|
|
10
|
+
static get properties() {
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mutationObserver = new MutationObserverController(this, { characterData: true, attributes: false, childList: true, subtree: true });
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
createRenderRoot() {
|
|
21
|
+
this.style.display = 'none';
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_onChildListMutation() {
|
|
26
|
+
// send event to ucdlib-md
|
|
27
|
+
this.dispatchEvent(new CustomEvent('content-updated', { bubbles: true }));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
customElements.define('ucdlib-md-content', UcdlibMdContent);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { LitElement, css } from 'lit';
|
|
2
|
+
import { marked } from 'marked';
|
|
3
|
+
import DOMPurify from 'dompurify';
|
|
4
|
+
import { UcdlibMdContent } from './ucdlib-md-content.js';
|
|
5
|
+
import { MutationObserverController } from '../../utils/controllers/mutation-observer.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class UcdlibMd
|
|
9
|
+
* @classdesc Component class for translating/displaying markdown into sanitized html
|
|
10
|
+
* @property {String} data - text to hold markdown code
|
|
11
|
+
* @property {Object} renderer - an object holding element functions to override the default markdown behavior
|
|
12
|
+
* Format: reference the Marked Renderer documentation at https://marked.js.org/using_pro#renderer
|
|
13
|
+
* @property {Object} use - marked use object
|
|
14
|
+
* @property {Object} options - marked options object
|
|
15
|
+
*/
|
|
16
|
+
export default class UcdlibMd extends LitElement {
|
|
17
|
+
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
// ignore: {type: String},
|
|
21
|
+
// exclude: {type: String},
|
|
22
|
+
// subset: {type: String},
|
|
23
|
+
data: {type: String},
|
|
24
|
+
renderer: {type: Object},
|
|
25
|
+
use: {type: Object},
|
|
26
|
+
options: {type: Object}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
mutationObserver = new MutationObserverController(this, { characterData: true, attributes: false, childList: true, subtree: true });
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.data = '';
|
|
35
|
+
this.renderer = null;
|
|
36
|
+
|
|
37
|
+
this.renderedElement = document.createElement('div');
|
|
38
|
+
this.renderedElement.setAttribute('rendered', '');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
createRenderRoot() {
|
|
42
|
+
this.appendChild(this.renderedElement);
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_onChildListMutation() {
|
|
47
|
+
if( this.contentElement ) return;
|
|
48
|
+
|
|
49
|
+
// query children for ucdlib-md-content
|
|
50
|
+
// wire up listener if it exists
|
|
51
|
+
this.contentElement = this.querySelector('ucdlib-md-content');
|
|
52
|
+
if( this.contentElement ) {
|
|
53
|
+
this.contentElement.addEventListener('content-updated', this._updateFromContentElementMd.bind(this));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
disconnectedCallback() {
|
|
58
|
+
if( this.contentElement ) {
|
|
59
|
+
this.contentElement.removeEventListener('content-updated', this._updateFromContentElementMd.bind(this));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @method updated
|
|
65
|
+
* @description Lit method called when element is updated.
|
|
66
|
+
*/
|
|
67
|
+
updated() {
|
|
68
|
+
// config markdown renderer so elements are correctly styled
|
|
69
|
+
this._setRendererOverrides();
|
|
70
|
+
|
|
71
|
+
// update markdown data with the latest, either when the content changes or data property is updated
|
|
72
|
+
this.data = DOMPurify.sanitize(marked.parse(this.data));
|
|
73
|
+
this.renderedElement.innerHTML = this.data;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @method _updateFromContentElementMd
|
|
78
|
+
* @description Updates the local data property with the text from the ucdlib-md-content element (if it exists)
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
_updateFromContentElementMd() {
|
|
82
|
+
// remove whitespace between lines
|
|
83
|
+
this.data = this.contentElement.innerText.split('\n').map(line => line.trim()).join('\n');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @method _setRendererOverrides
|
|
88
|
+
* @description Updates the marked package renderer overrides to customize how element types are rendered
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
_setRendererOverrides() {
|
|
92
|
+
if (!this.renderer) {
|
|
93
|
+
this.renderer = {
|
|
94
|
+
list(body, ordered, start) {
|
|
95
|
+
let renderedContent = '';
|
|
96
|
+
if (ordered) {
|
|
97
|
+
renderedContent = `<ul class="list--multilevel">${body}</ul>`;
|
|
98
|
+
} else {
|
|
99
|
+
renderedContent = `<ul class="list--bordered">${body}</ul>`;
|
|
100
|
+
}
|
|
101
|
+
return renderedContent;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!this.options) {
|
|
107
|
+
this.options = { breaks: true, gfm: true };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!this.use) {
|
|
111
|
+
this.use = { renderer: this.renderer };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
marked.use(this.use);
|
|
115
|
+
marked.setOptions(this.options);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
customElements.define('ucdlib-md', UcdlibMd);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# SILS Permalink
|
|
2
|
+
|
|
3
|
+
Allows users to easily add links to SILS permalinks in webpages.
|
|
4
|
+
|
|
5
|
+
## Inline Version
|
|
6
|
+
|
|
7
|
+
By default add simple links to the pages. If you identified a tag inline like
|
|
8
|
+
`<ucdlib-sils-permalink
|
|
9
|
+
href="https://search.library.ucdavis.edu/permalink/01UCD_INST/1uov27j/alma9981249369903126"/>`,
|
|
10
|
+
then the link would format as something like
|
|
11
|
+
|
|
12
|
+
* [Engineering victory : the Union siege of
|
|
13
|
+
Vicksburg](https://search.library.ucdavis.edu/permalink/01UCD_INST/1uov27j/alma9981249369903126)
|
|
14
|
+
|
|
15
|
+
For more citation information, we'd could add
|
|
16
|
+
|
|
17
|
+
* `<ucdlib-sils-permalink href=".." cite="full" />` => [Solonick, Justin
|
|
18
|
+
S. Engineering Victory : the Union Siege of Vicksburg . Carbondale: Southern
|
|
19
|
+
Illinois University
|
|
20
|
+
Press, 2015. Print.](https://search.library.ucdavis.edu/permalink/01UCD_INST/1uov27j/alma9981249369903126)
|
|
21
|
+
|
|
22
|
+
## Expanded Version
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Task} from '@lit-labs/task';
|
|
2
|
+
|
|
3
|
+
export class PermalinkController {
|
|
4
|
+
// host;
|
|
5
|
+
// value;
|
|
6
|
+
// kinds = Names.kinds;
|
|
7
|
+
// task;
|
|
8
|
+
constructor(host, url) {
|
|
9
|
+
const baseUrl = url;
|
|
10
|
+
this.url = baseUrl;
|
|
11
|
+
this.host = host;
|
|
12
|
+
this.task = new Task(
|
|
13
|
+
this.host,
|
|
14
|
+
async () => {
|
|
15
|
+
const response = await fetch(`${baseUrl}`);
|
|
16
|
+
const result = await response.json();
|
|
17
|
+
const error = result.error;
|
|
18
|
+
if (error !== undefined) {
|
|
19
|
+
throw new Error(error);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
() => [this.url]
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
render(renderFunctions) {
|
|
31
|
+
return this.task.render(renderFunctions);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { LitElement} from 'lit';
|
|
2
|
+
import {render, styles} from "./ucdlib-sils-permalink.tpl.js";
|
|
3
|
+
import {PermalinkController} from './ucdlib-sils-permalink-controller.js';
|
|
4
|
+
import {TaskController} from '../../utils/controllers/task.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @class UcdlibSilsPermalink
|
|
8
|
+
* @description This component allows you to easily add individual objects from
|
|
9
|
+
* the UC SILS catalog into your webpage.
|
|
10
|
+
* @property {String} href - Pointer to the permalink
|
|
11
|
+
* @property {String} cite - Specify the citation style
|
|
12
|
+
*
|
|
13
|
+
* <ucdlib-sils-permalink href="https://search.library.ucdavis.edu/permalink/01UCD_INST/1uov27j/alma9981249369903126"/>
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export default class UcdlibSilsPermalink extends LitElement {
|
|
17
|
+
static get properties() {
|
|
18
|
+
return {
|
|
19
|
+
results : {type: Object, attribute:false},
|
|
20
|
+
permalink : {type: String},
|
|
21
|
+
image : {type: String},
|
|
22
|
+
title : {type: String},
|
|
23
|
+
authorFull : {type: String},
|
|
24
|
+
authorLast : {type: String, attribute:false},
|
|
25
|
+
authorFirst: {type: String, attribute:false},
|
|
26
|
+
authorID: {type: Array, attribute:false},
|
|
27
|
+
year : { type: String},
|
|
28
|
+
summary : {type: String},
|
|
29
|
+
tags : {type: Array},
|
|
30
|
+
host_url : {type: String},
|
|
31
|
+
teaserType : {type: String, attribute:false},
|
|
32
|
+
publisher : {type: String, attribute:false},
|
|
33
|
+
placePublication : {type: String, attribute:false},
|
|
34
|
+
notes : {type: Array, attribute:false},
|
|
35
|
+
language: {type: String, attribute:false},
|
|
36
|
+
randomClass: {type: String, attribute:false},
|
|
37
|
+
elemClass: {type: Array, attribute:false},
|
|
38
|
+
url: {type: String, attribute:false},
|
|
39
|
+
form: {type: Boolean, attribute:false},
|
|
40
|
+
isCustom: {type:Boolean},
|
|
41
|
+
index: {type:Number},
|
|
42
|
+
newPermalink: {type: Array, hasChanged(newVal, oldVal) {
|
|
43
|
+
return newVal !== oldVal;
|
|
44
|
+
}, attribute:false},
|
|
45
|
+
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static get styles() {
|
|
50
|
+
return styles();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
super();
|
|
55
|
+
this.PENDING = false;
|
|
56
|
+
this.LOADING = false;
|
|
57
|
+
this.COMPLETE = false;
|
|
58
|
+
this.ERROR = false;
|
|
59
|
+
this.results = {};
|
|
60
|
+
this.loading = false;
|
|
61
|
+
this.resultsPerPage = 9999;
|
|
62
|
+
this.page = 1;
|
|
63
|
+
this.permalink = '';
|
|
64
|
+
this.authorLast = '';
|
|
65
|
+
this.authorFirst = '';
|
|
66
|
+
this.authorFull = '';
|
|
67
|
+
this.title = '';
|
|
68
|
+
this.year = '';
|
|
69
|
+
this.summary= '';
|
|
70
|
+
this.host_url= '';
|
|
71
|
+
this.tags = [];
|
|
72
|
+
this.authorID = [];
|
|
73
|
+
this.teaserType = '';
|
|
74
|
+
this.publisher = '';
|
|
75
|
+
this.placePublication = '';
|
|
76
|
+
this.notes = [];
|
|
77
|
+
this.language = '';
|
|
78
|
+
this.randomClass = '';
|
|
79
|
+
this.elemClass = ['tahoe', 'california', 'quad'];
|
|
80
|
+
this.image = '';
|
|
81
|
+
this.url = '';
|
|
82
|
+
this.isCustom = false;
|
|
83
|
+
this.newPermalink = [];
|
|
84
|
+
this.form = false;
|
|
85
|
+
this.index = 0;
|
|
86
|
+
this.tagEntryField = [{url: '', label: '', default: true}];
|
|
87
|
+
this.authorEntryField = [{value: '', default: true}];
|
|
88
|
+
this.errorMessage = 'Href is not a permalink.';
|
|
89
|
+
this.render=render.bind(this);
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @method firstUpdated
|
|
95
|
+
*
|
|
96
|
+
* @description updated when the page first renders
|
|
97
|
+
*
|
|
98
|
+
* @param {Object} changedProperties
|
|
99
|
+
*
|
|
100
|
+
*/
|
|
101
|
+
firstUpdated(changedProperties){
|
|
102
|
+
if(this.permalink != ''){
|
|
103
|
+
this.perma = new TaskController(this, this._requestUrl());
|
|
104
|
+
|
|
105
|
+
this.requestUpdate();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
validationLink(url){
|
|
114
|
+
// let match = url.match(/([^\/]+)([a-z0-9]+)$/g);
|
|
115
|
+
|
|
116
|
+
// let id = url.includes("/9fle3i/") ? 'L' : url.includes("/1hjlc2p/") ? 'PC' : 'Error';
|
|
117
|
+
// if(url.match(/https:\/\/search.library.ucdavis.edu\/permalink\/01UCD_INST\/([^\/]+)\/([a-zA-Z0-9_]*)/g)){
|
|
118
|
+
// url = 'https://search.library.ucdavis.edu/primaws/rest/pub/pnxs/' + id + '/' + match[0] +'?vid=01UCD_INST:UCD&lang=en&search_scope=DN_and_CI';
|
|
119
|
+
// return url;
|
|
120
|
+
// }
|
|
121
|
+
let id;
|
|
122
|
+
if(url != "") id = url.split("/alma")[1];
|
|
123
|
+
|
|
124
|
+
url = "https://open-na.hosted.exlibrisgroup.com/alma/01UCD_INST/bibs/" + id;
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
return url;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
_onPending(){
|
|
131
|
+
this.PENDING = true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
_onError(e){
|
|
136
|
+
this.ERROR = true;
|
|
137
|
+
console.log("Error:", e);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
handleEdit() {
|
|
141
|
+
this.form = true;
|
|
142
|
+
|
|
143
|
+
this.requestUpdate();
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
handleDelete(){
|
|
147
|
+
let tempDelete = JSON.parse(sessionStorage.getItem("newPermalink"));
|
|
148
|
+
|
|
149
|
+
delete tempDelete[this.index];
|
|
150
|
+
tempDelete = Object.fromEntries(Object.entries(tempDelete).filter(([_, v]) => v != null));
|
|
151
|
+
|
|
152
|
+
this.requestUpdate;
|
|
153
|
+
sessionStorage.setItem("newPermalink", JSON.stringify(tempDelete));
|
|
154
|
+
location.reload();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @method _addTag
|
|
160
|
+
*
|
|
161
|
+
* @description Bound to click event on website add button. adds another
|
|
162
|
+
* iteration of the element to the DOM and List
|
|
163
|
+
*
|
|
164
|
+
* @param {Object} element
|
|
165
|
+
*
|
|
166
|
+
*/
|
|
167
|
+
_addTag(){
|
|
168
|
+
this.tagEntryField.push({url: '', label: '', default: false});
|
|
169
|
+
this.requestUpdate();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @method _addAuthor
|
|
174
|
+
*
|
|
175
|
+
* @description Bound to click event of add email button.
|
|
176
|
+
* adds another iteration of the element to the DOM and List
|
|
177
|
+
*
|
|
178
|
+
* @param {Object} element
|
|
179
|
+
*
|
|
180
|
+
*/
|
|
181
|
+
_addAuthor(){
|
|
182
|
+
this.authorEntryField.push({value: '', default: false});
|
|
183
|
+
this.requestUpdate();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @method _sendValues
|
|
188
|
+
*
|
|
189
|
+
* @description Get the values from the form that is given.
|
|
190
|
+
*
|
|
191
|
+
* @param {Object} element
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
_sendValues(){
|
|
195
|
+
let formData = {};
|
|
196
|
+
let authorList = [];
|
|
197
|
+
let tagtitle = [];
|
|
198
|
+
let url = [];
|
|
199
|
+
let image = [];
|
|
200
|
+
let tags = [];
|
|
201
|
+
|
|
202
|
+
formData.title = this.shadowRoot.getElementById("permalink-title").value;
|
|
203
|
+
formData.year = this.shadowRoot.getElementById("permalink-date").value;
|
|
204
|
+
formData.summary = this.shadowRoot.getElementById("permalink-summary").value;
|
|
205
|
+
formData.image = this.shadowRoot.getElementById("permalink-image").value;
|
|
206
|
+
formData.permalink = this.shadowRoot.getElementById("permalink-permalink").value;
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
for(let i of this.shadowRoot.querySelectorAll("[id^='permalink-author']").values()){
|
|
210
|
+
authorList.push({"label" : i.value});
|
|
211
|
+
}
|
|
212
|
+
formData.author = authorList;
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
for(let i of this.shadowRoot.querySelectorAll("[id^='permalink-image']").values())
|
|
216
|
+
image.push(i.value);
|
|
217
|
+
formData.image = image[0];
|
|
218
|
+
|
|
219
|
+
for(let i of this.shadowRoot.querySelectorAll("[id^='permalink-tags ']").values())
|
|
220
|
+
tagtitle.push(i.value);
|
|
221
|
+
|
|
222
|
+
for(let i of this.shadowRoot.querySelectorAll("[id^='permalink-tags-url']").values())
|
|
223
|
+
url.push(i.value);
|
|
224
|
+
|
|
225
|
+
for(let i in tagtitle)
|
|
226
|
+
tags[i] = {"@id": url[i], "label": tagtitle[i]};
|
|
227
|
+
formData.tags = tags;
|
|
228
|
+
|
|
229
|
+
if(sessionStorage.getItem("newPermalink")){
|
|
230
|
+
this.newPermalink = JSON.parse(sessionStorage.getItem("newPermalink"));
|
|
231
|
+
this.newPermalink = Object.values(this.newPermalink);
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
this.newPermalink.push(formData);
|
|
236
|
+
|
|
237
|
+
this.form = false;
|
|
238
|
+
|
|
239
|
+
this.requestUpdate;
|
|
240
|
+
sessionStorage.setItem("newPermalink", JSON.stringify(this.newPermalink));
|
|
241
|
+
location.reload();
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getCreatedPermalink(){
|
|
247
|
+
super.requestUpdate();
|
|
248
|
+
|
|
249
|
+
return this.newPermalink;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
_onComplete(results){
|
|
254
|
+
|
|
255
|
+
/* Note:
|
|
256
|
+
ISBN has multiple options so later address which items to pick and whether
|
|
257
|
+
to use default thumbnail
|
|
258
|
+
*/
|
|
259
|
+
|
|
260
|
+
this.COMPLETE = true;
|
|
261
|
+
this.PENDING = false;
|
|
262
|
+
this.LOADING = false;
|
|
263
|
+
this.results = results;
|
|
264
|
+
this.teaserType = this.results["@type"];
|
|
265
|
+
let img = [];
|
|
266
|
+
for(let i = 0; i < this.results.identifier.length; i++){
|
|
267
|
+
if(this.results.identifier[i]['@type']){
|
|
268
|
+
if(this.results.identifier[i]['@type'].includes('bibo:isbn'))
|
|
269
|
+
img = img.concat(this.results.identifier[i].label);
|
|
270
|
+
if(this.results.identifier[i]['@type'].includes('bibo:ean'))
|
|
271
|
+
img = img.concat(this.results.identifier[i].label);
|
|
272
|
+
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
}
|
|
276
|
+
let identifer = img[0];
|
|
277
|
+
|
|
278
|
+
if(this.teaserType == 'Video' || this.teaserType == 'Music'){
|
|
279
|
+
this.image = 'https://syndetics.com/index.php?client=primo&isbn='+ identifer + '/sc.gif';
|
|
280
|
+
}
|
|
281
|
+
else{
|
|
282
|
+
this.image = 'https://syndetics.com/index.php?client=primo&isbn='+ identifer + '/sc.jpg';
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this.year = this.results.date;
|
|
286
|
+
this.title = this.results.title.substring(0, this.results.title.lastIndexOf("/"));
|
|
287
|
+
this.authorFull = !Array.isArray(this.results.creator) ? [this.results.creator] : this.results.creator;
|
|
288
|
+
|
|
289
|
+
this.authorLast = this.authorFull[0];
|
|
290
|
+
this.authorFirst = this.authorFull[1];
|
|
291
|
+
this.summary = this.results.description;
|
|
292
|
+
this.publisher = this.results.publisher;
|
|
293
|
+
this.placePublication = this.results.place_of_publication.split(' ')[0];
|
|
294
|
+
this.language = this.results.language;
|
|
295
|
+
|
|
296
|
+
for (let i = 0; i < Object.keys(this.results.subject).length; i++){
|
|
297
|
+
this.tags = this.tags.concat({"id": this.results.subject[i]["@id"], "subject": this.results.subject[i]["label"]});
|
|
298
|
+
}
|
|
299
|
+
this.tags = this.results.subject;
|
|
300
|
+
|
|
301
|
+
this.notes = this.results.note;
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
_requestUrl(){
|
|
307
|
+
let url =this.permalink;
|
|
308
|
+
let validate = this.validationLink(url);
|
|
309
|
+
if(validate == this.errorMessage) console.error(url);
|
|
310
|
+
this.requestUpdate();
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
url = validate;
|
|
314
|
+
return url;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
_onLoading(){
|
|
318
|
+
this.LOADING = true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
customElements.define('ucdlib-sils-permalink',UcdlibSilsPermalink);
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
import normalizeCss from "@ucd-lib/theme-sass/normalize.css.js";
|
|
4
|
+
import teaserStyles from "@ucd-lib/theme-sass/4_component/_index.css.js";
|
|
5
|
+
import baseStyles from "@ucd-lib/theme-sass/1_base_html/_index.css.js";
|
|
6
|
+
import buttons from "@ucd-lib/theme-sass/2_base_class/_index.css.js";
|
|
7
|
+
export function styles() {
|
|
8
|
+
const elementStyles = css`
|
|
9
|
+
:host {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
form {
|
|
13
|
+
width:100%;
|
|
14
|
+
}
|
|
15
|
+
#tag {
|
|
16
|
+
width:75%;
|
|
17
|
+
display: inline-block;
|
|
18
|
+
}
|
|
19
|
+
#tag-color {
|
|
20
|
+
width:24%;
|
|
21
|
+
display: inline-block;
|
|
22
|
+
}
|
|
23
|
+
#delete {
|
|
24
|
+
width:24%;
|
|
25
|
+
display: inline-block;
|
|
26
|
+
}
|
|
27
|
+
#permalink-author {
|
|
28
|
+
width:75%;
|
|
29
|
+
display: inline-block;
|
|
30
|
+
}
|
|
31
|
+
#permalink-tags {
|
|
32
|
+
width:75%;
|
|
33
|
+
display: inline-block;
|
|
34
|
+
}
|
|
35
|
+
#permalink-tags-url {
|
|
36
|
+
width:75%;
|
|
37
|
+
display: inline-block;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
return [elementStyles,baseStyles,teaserStyles,normalizeCss, buttons];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function render() {
|
|
47
|
+
return html`
|
|
48
|
+
<style>
|
|
49
|
+
.vm-teaser__figure.category_loading{
|
|
50
|
+
background-color:#dcdcdc;
|
|
51
|
+
height:165px;
|
|
52
|
+
width:135px;
|
|
53
|
+
}
|
|
54
|
+
.load_teaser_a{
|
|
55
|
+
background-color:#dcdcdc;
|
|
56
|
+
width: 85%;
|
|
57
|
+
height:25px;
|
|
58
|
+
}
|
|
59
|
+
.load_teaser_b{
|
|
60
|
+
background-color:#dcdcdc;
|
|
61
|
+
width: 67%;
|
|
62
|
+
height:20px;
|
|
63
|
+
}
|
|
64
|
+
.load_teaser_c{
|
|
65
|
+
background-color:#dcdcdc;
|
|
66
|
+
width: 33.3%;
|
|
67
|
+
height:18px;
|
|
68
|
+
}
|
|
69
|
+
</style>
|
|
70
|
+
<!--
|
|
71
|
+
Starts the Permalink Fetch
|
|
72
|
+
-->
|
|
73
|
+
${this.perma ? html`
|
|
74
|
+
${this.perma.render({
|
|
75
|
+
complete: (result) => this._onComplete(result),
|
|
76
|
+
initial: () => this._onLoading(),
|
|
77
|
+
pending: () => this._onPending(),
|
|
78
|
+
error: (e) => this._onError(e)
|
|
79
|
+
})
|
|
80
|
+
}`:html``
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
<article class="vm-teaser ">
|
|
84
|
+
${!this.LOADING ? html`
|
|
85
|
+
<!--
|
|
86
|
+
If it is completed permalink fetch
|
|
87
|
+
-->
|
|
88
|
+
${!this.form ?
|
|
89
|
+
|
|
90
|
+
html`
|
|
91
|
+
<!--
|
|
92
|
+
This is the original permalink read that fires if there is are
|
|
93
|
+
attributes added to the permalink. If the form is not triggered
|
|
94
|
+
-->
|
|
95
|
+
|
|
96
|
+
<div class="vm-teaser__figure category">
|
|
97
|
+
<a href="${this.image}"><img src="${this.image}" alt="" class="" width="135" loading="eager" />
|
|
98
|
+
</a>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="vm-teaser__body">
|
|
101
|
+
<h3 class="vm-teaser__title"><a href="${this.host_url ? this.host_url : this.permalink}">${this.title}</a></h3>
|
|
102
|
+
|
|
103
|
+
<ul class="vm-teaser__byline">
|
|
104
|
+
<li>
|
|
105
|
+
|
|
106
|
+
${this.authorFull ?
|
|
107
|
+
typeof this.authorFull === 'string' || this.authorFull instanceof String ?
|
|
108
|
+
JSON.parse(this.authorFull).map(author => author["label"] != "" ? html`<span class="byline"> ${author["label"]}.</span>--<br />` : html``)
|
|
109
|
+
:this.authorFull.map(author => author["label"] != "" ? html`<span class="byline"> ${author["label"]}.</span>--<br />` : html``)
|
|
110
|
+
:html``
|
|
111
|
+
}
|
|
112
|
+
</li>
|
|
113
|
+
<li>${this.year}</li>
|
|
114
|
+
</ul>
|
|
115
|
+
<ul class="vm-teaser__categories">
|
|
116
|
+
${this.tags ?
|
|
117
|
+
typeof this.tags === 'string' || this.tags instanceof String ?
|
|
118
|
+
JSON.parse(this.tags).map(tag => html`<li class="vm-teaser__cat-marker tahoe"><a href="${tag['@id']}">${tag['label']}</a></li>`)
|
|
119
|
+
:this.tags.map(tag => tag["label"] != "" ? html`<li class="vm-teaser__cat-marker ${this.elemClass[Math.floor(Math.random() * this.elemClass.length)]}"><a href="${tag['@id']}">${tag['label']}</a></li>`:html``)
|
|
120
|
+
:html``
|
|
121
|
+
}
|
|
122
|
+
</ul>
|
|
123
|
+
<div class="vm-teaser__summary">${this.summary}</div>
|
|
124
|
+
</div>
|
|
125
|
+
${this.isCustom ? html`
|
|
126
|
+
<button id="delete-permalink" class="btn btn--alt2" @click="${this.handleDelete}">Delete Permalink</button>
|
|
127
|
+
|
|
128
|
+
`: html`
|
|
129
|
+
<button id="edit-permalink" class="btn--primary" @click="${this.handleEdit}">Edit Permalink</button>
|
|
130
|
+
`}
|
|
131
|
+
|
|
132
|
+
`:html`
|
|
133
|
+
<!--
|
|
134
|
+
This is if the form is triggered meaning the edit permalink is occuring
|
|
135
|
+
so that it adds to the entries to the session. Also takes info from what
|
|
136
|
+
is already in the permalink. This is the edit form
|
|
137
|
+
-->
|
|
138
|
+
<form method="post">
|
|
139
|
+
<!-- START OF FORM -->
|
|
140
|
+
|
|
141
|
+
<fieldset>
|
|
142
|
+
|
|
143
|
+
<!-- Title -->
|
|
144
|
+
<div class="field-container">
|
|
145
|
+
<label for="permalink-title">Title</label>
|
|
146
|
+
<input id="permalink-title" .value=${this.title ? this.title : ""} type="text" placeholder=${this.title ? this.title : "Enter Your Title"} />
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<!-- Host URL -->
|
|
150
|
+
<div class="field-container">
|
|
151
|
+
<label for="permalink-permalink">Permalink Host URL</label>
|
|
152
|
+
<input id="permalink-permalink" .value=${this.permalink ? this.permalink : ""} type="text" placeholder=${this.permalink ? this.permalink : "Enter Your Title"} />
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
<br />
|
|
157
|
+
<br />
|
|
158
|
+
<br />
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
<!-- Author -->
|
|
162
|
+
${this.authorFull ?
|
|
163
|
+
html`
|
|
164
|
+
<!-- If permalink already has authors -->
|
|
165
|
+
<div class="author">
|
|
166
|
+
<div style="border-style: solid; margin: 25px 0; padding:5px;">
|
|
167
|
+
${this.authorFull.map((author, index) =>
|
|
168
|
+
html`
|
|
169
|
+
<div class="field-container">
|
|
170
|
+
<label for="permalink-author no-${index}">Author</label>
|
|
171
|
+
<input id="permalink-author no-${index}" type="author" .value=${author['label']} placeholder="${author['label'].split(",")[0]}, ${author['label'].split(",")[1] ? author['label'].split(",")[1] : ""} " />
|
|
172
|
+
</div> `
|
|
173
|
+
)}
|
|
174
|
+
</div>
|
|
175
|
+
<br />
|
|
176
|
+
<div>
|
|
177
|
+
|
|
178
|
+
<h5>New Author Entry</h5>
|
|
179
|
+
${this.authorEntryField.map((item, index) =>
|
|
180
|
+
html`
|
|
181
|
+
<div class="field-container">
|
|
182
|
+
<label for="permalink-author no-${index}">Author</label>
|
|
183
|
+
<input id="permalink-author no-${index}" type="author" .value=${item.value} placeholder="Enter the Authors of the Work" />
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
`
|
|
187
|
+
)}
|
|
188
|
+
<a @click="${this._addAuthor}" class="btn--alt3 btn--sm" >Add Author Field</a>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
`
|
|
192
|
+
:html`
|
|
193
|
+
<!-- If permalink DOES NOT has authors -->
|
|
194
|
+
|
|
195
|
+
<div>
|
|
196
|
+
|
|
197
|
+
<div class="author">
|
|
198
|
+
<br />
|
|
199
|
+
<h5>New Author Entry</h5>
|
|
200
|
+
${this.authorEntryField.map((item, index) =>
|
|
201
|
+
html`
|
|
202
|
+
<div class="field-container">
|
|
203
|
+
<label for="permalink-author no-${index}">Author</label>
|
|
204
|
+
<input id="permalink-author no-${index}" type="author" .value=${item.value} placeholder="Enter the Authors of the Work" />
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
`
|
|
208
|
+
)}
|
|
209
|
+
<a @click="${this._addAuthor}" class="btn--alt3 btn--sm" >Add Author Field</a>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
`}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
<br />
|
|
216
|
+
<br />
|
|
217
|
+
<br />
|
|
218
|
+
|
|
219
|
+
<!-- Year -->
|
|
220
|
+
<div class="field-container">
|
|
221
|
+
<label for="permalink-date">Year of Publication</label>
|
|
222
|
+
<input id="permalink-date" value=${this.year ? this.year : ""} type="text" placeholder=${this.year ? this.year : "Year of Publication"} />
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<!-- Image -->
|
|
226
|
+
<div class="field-container">
|
|
227
|
+
<label for="permalink-image">Image JPEG URL</label>
|
|
228
|
+
<input id="permalink-image" value=${this.image ? this.image : ""} type="url" placeholder=${this.year ? this.year : "Year of Publication"} />
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<br />
|
|
232
|
+
<br />
|
|
233
|
+
<br />
|
|
234
|
+
|
|
235
|
+
<!-- Tags -->
|
|
236
|
+
${this.tags ?
|
|
237
|
+
html`
|
|
238
|
+
|
|
239
|
+
<!-- If permalink already has Tags -->
|
|
240
|
+
<div class="tag">
|
|
241
|
+
<div style="border-style: solid; margin: 25px 0; padding:5px;">
|
|
242
|
+
${this.tags.map((tag, index)=>
|
|
243
|
+
html`
|
|
244
|
+
<div id="tag" class="field-container">
|
|
245
|
+
<label for="permalink-tags no-${index}">Tag</label>
|
|
246
|
+
<input id="permalink-tags no-${index}" type="url" .value=${tag['label']} placeholder="${tag['label']}" />
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<label for="permalink-tags-url no-${index}">URL</label>
|
|
250
|
+
<input id="permalink-tags-url no-${index}" .value=${tag['@id'] ? tag['@id']: ''} type="url" placeholder="${tag['@id'] ? tag['@id']: 'URL Not Defined'}" />
|
|
251
|
+
|
|
252
|
+
<br />
|
|
253
|
+
<br />
|
|
254
|
+
<br />
|
|
255
|
+
`
|
|
256
|
+
)}
|
|
257
|
+
</div>
|
|
258
|
+
|
|
259
|
+
<h5>New Tag Entry</h5>
|
|
260
|
+
${this.tagEntryField.map((item, index) =>
|
|
261
|
+
html`
|
|
262
|
+
<div class="tag">
|
|
263
|
+
<div id="tag" class="field-container">
|
|
264
|
+
<label for="permalink-tags no-${index}">Tag</label>
|
|
265
|
+
<input id="permalink-tags no-${index}" type="url" .value=${item.label} placeholder="Name Your Permalink Tag" />
|
|
266
|
+
<label for="permalink-tags-url no-${index}">URL</label>
|
|
267
|
+
<input id="permalink-tags-url no-${index}" .value=${item.url} type="url" placeholder="URL of Permalink Tag" />
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
`
|
|
271
|
+
)}
|
|
272
|
+
|
|
273
|
+
<br />
|
|
274
|
+
<a @click="${this._addTag}" id="form-apply"class="btn--alt3 btn--sm">Add Tag Field</a>
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
`:html `
|
|
278
|
+
<!-- If permalink DOES NOT has Tags -->
|
|
279
|
+
<h5>New Tag Entry</h5>
|
|
280
|
+
${this.tagEntryField.map((item, index) =>
|
|
281
|
+
html`
|
|
282
|
+
<div class="tag">
|
|
283
|
+
<div id="tag" class="field-container">
|
|
284
|
+
<label for="permalink-tags no-${index}">Tag</label>
|
|
285
|
+
<input id="permalink-tags no-${index}" type="url" .value=${item.label} placeholder="Name Your Permalink Tag" />
|
|
286
|
+
<label for="permalink-tags-url no-${index}">URL</label>
|
|
287
|
+
<input id="permalink-tags-url no-${index}" .value=${item.url} type="url" placeholder="URL of Permalink Tag" />
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
`
|
|
291
|
+
|
|
292
|
+
)}
|
|
293
|
+
|
|
294
|
+
<br />
|
|
295
|
+
<a @click="${this._addTag}" id="form-apply"class="btn--alt3 btn--sm">Add Tag Field</a>
|
|
296
|
+
|
|
297
|
+
`}
|
|
298
|
+
|
|
299
|
+
<br />
|
|
300
|
+
<!-- Summary -->
|
|
301
|
+
<div class="field-container">
|
|
302
|
+
<label for="permalink-summary">Summary</label>
|
|
303
|
+
<textarea id="permalink-summary" .value=${this.summary ? this.summary : ""} rows="5" placeholder=${this.summary ? this.summary : "Write Summary Here"}></textarea>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
</fieldset>
|
|
308
|
+
|
|
309
|
+
<!-- Apply Button -->
|
|
310
|
+
<div class="field-container--small views-filters__submit-field">
|
|
311
|
+
<a @click="${this._sendValues}" class="btn--primary">Apply</a>
|
|
312
|
+
<a onClick="window.location.reload();" class="btn--alt">Cancel</a>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
<!-- END OF FORM -->
|
|
316
|
+
</form>
|
|
317
|
+
`}
|
|
318
|
+
`:html`
|
|
319
|
+
<!--
|
|
320
|
+
If it is in the loading stage of the permalink fetch
|
|
321
|
+
it will render this
|
|
322
|
+
look.
|
|
323
|
+
-->
|
|
324
|
+
<div class="vm-teaser__figure category_loading"></div>
|
|
325
|
+
<div class="vm-teaser__body">
|
|
326
|
+
<div class="load_teaser_a"></div>
|
|
327
|
+
<br/>
|
|
328
|
+
<div class="load_teaser_b"></div>
|
|
329
|
+
<br/>
|
|
330
|
+
<div class="load_teaser_c"></div>
|
|
331
|
+
<br/>
|
|
332
|
+
<div class="load_teaser_c"></div>
|
|
333
|
+
</div>
|
|
334
|
+
`}
|
|
335
|
+
</article>
|
|
336
|
+
`;
|
|
337
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Task} from '@lit-labs/task';
|
|
2
|
+
|
|
3
|
+
export class TaskController {
|
|
4
|
+
// host;
|
|
5
|
+
// value;
|
|
6
|
+
// kinds = Names.kinds;
|
|
7
|
+
// task;
|
|
8
|
+
constructor(host, url) {
|
|
9
|
+
const baseUrl = url;
|
|
10
|
+
this.url = baseUrl;
|
|
11
|
+
this.host = host;
|
|
12
|
+
this.task = new Task(
|
|
13
|
+
this.host,
|
|
14
|
+
async () => {
|
|
15
|
+
const response = await fetch(`${baseUrl}`);
|
|
16
|
+
const result = await response.json();
|
|
17
|
+
const error = result.error;
|
|
18
|
+
if (error !== undefined) {
|
|
19
|
+
throw new Error(error);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
() => [this.url]
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
render(renderFunctions) {
|
|
31
|
+
return this.task.render(renderFunctions);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
}
|